home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / program / slix0987.zip / SLIX0987.BAS < prev    next >
BASIC Source File  |  1996-08-10  |  114KB  |  2,991 lines

  1. '$DYNAMIC
  2.  
  3. 'slix0987.BAS
  4.  
  5. '.--------------------------------------------------------------.
  6. '|                         .------------.                       |
  7. '|                         | slix 0.987 |                       |
  8. '|                         `------------'                       |
  9. '|                                                              |
  10. '|                  sprite library for mode x                   |
  11. '|                  (and other tweaked modes)                   |
  12. '|              Full QuickBASIC source code included            |
  13. '|                                                              |
  14. '|                     Written by Lloyd Chang                   |
  15. '|                         August 10, 1996                      |
  16. '|                                                              |
  17. '|                  FREEWARE, NOT PUBLIC DOMAIN!                |
  18. '|                                                              |
  19. '`--------------------------------------------------------------'
  20.  
  21. '   #########################################################
  22. '   # DISCLAIMER: USE slix AT YOUR OWN RISK!                #
  23. '   #             The author is not liable for any problems #
  24. '   #             that may result from the use of slix.     #
  25. '   #                                                       #
  26. '   #########################################################
  27.  
  28. '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  29. '% slix is FREEWARE.  The program may be freely distributed    %
  30. '% under the condition that the author be given credit for     %
  31. '% slix.  Modifications are encouraged.                        %
  32. '% Feel free to contact me if modifications are made to any    %
  33. '% part of slix.                                               %
  34. '%                                                             %
  35. '% There are currently no other restrictions with regard to    %
  36. '% the use of slix.                                            %
  37. '%                                                             %
  38. '%     **************************************************      %
  39. '%     * PLEASE READ THE DISCLAIMER BEFORE YOU USE slix *      %
  40. '%     **************************************************      %
  41. '%                                                             %
  42. '% I can be reached via:                                       %
  43. '%                                                             %
  44. '% Internet: lloyd.chang@tglbbs.com (!!The Game Line!!)        %
  45. '%  Fidonet: Lloyd Chang [1:278/304] (BlueDog)                 %
  46. '%                                                             %
  47. '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  48.  
  49. '----------------------------------------------------------------
  50.  
  51. 'Some people to thank...(in alphabetical order)
  52.  
  53. 'Michael Abrash -- For documenting Mode X in Dr. Dobb's Journal
  54. '                  [mabrash@bix.com]
  55. '                  [mabrash@mcimail.com]
  56.  
  57. 'Phil Carlisle -- Mode X FAQ
  58. '                 [pc@espr.demon.co.uk]
  59.  
  60. 'Carl Gorringe -- For showing interest in slix
  61.  
  62. 'Rich Geldreich -- Original GIF-displaying code
  63.  
  64. 'Themie Gouthas -- XLIB
  65. '                  [egg@dstos3.dsto.gov.au]
  66. '                  [teg@bart.dsto.gov.au]
  67.  
  68. 'Petri Hassinen -- Game Making Utilities
  69. '                  [phassine@alpha.hut.fi]
  70.  
  71. 'Petri Hodju -- Game Making Utilities
  72.  
  73. 'Saku Jalkanen -- Game Making Utilities (GRAPHICS)
  74.  
  75. 'Christopher G. Mann -- ASPHYXIA VGA trainer series
  76. '(a.k.a. Snowman)       [r3cgm@dax.cc.uakron.edu]
  77.  
  78. 'Robert Schmidt -- XINTRO & Tweak
  79. '(a.k.a. Buuud)    [robert@stud.unit.no]
  80.  
  81. 'Dave Shea -- For showing interest in slix
  82.  
  83. 'Grant Smith      -- ASPHYXIA VGA trainer series
  84. '(a.k.a. Denthor)    [smith9@batis.bis.und.ac.za]
  85.  
  86. 'Nikolai Soumarokov -- GNOOM II
  87.  
  88. 'Mike Valley -- Retrieving Mode X related info
  89. '               Numerous programming tips
  90.  
  91. '[zabudsk@ecf.utoronto.ca] -- Original BMP-displaying code
  92. '(Sorry, I should have contacted you for your real name)
  93.  
  94. 'Others -- Sorry if your name was not listed...
  95. '          Anyway, thanks!
  96.  
  97. '(I hope everyone's name was spelled correctly.)
  98.  
  99. 'If anyone above wish to have their internet e-mail address(es)
  100. 'listed in this document, please contact me.
  101.  
  102. 'Also, please contact me if I forgot to
  103. 'include someone's name in the above list.
  104.  
  105. '---------------------------------------------------------------
  106.  
  107. 'slix contains two other FREEWARE packages.
  108. 'They are GNOOM II & Game Making Utilities.  GNOOM II may be used to
  109. 'create GN2 files.  Game Making Utilities is included as a token of thanks
  110. 'for the use of GMU images in slix.  I have not yet made any contacts
  111. 'with either authors of GNOOM II or GMU.  Hopefully, Nikolai Soumarokov
  112. 'and Petri Hassinen, respectively, will not be offended by the inclusion
  113. 'of their programs.
  114.  
  115. '----------------------------------------------------------------
  116.  
  117. '                 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  118. '                 $$                          $$
  119. '                 $$ COMPILING SPEEDS UP slix $$
  120. '                 $$                          $$
  121. '                 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
  122.  
  123. 'Sorry.  slix is currently not available as
  124. 'a QuickBASIC Library (QLB format).  However,
  125. 'the user should be able to create a QLB on
  126. 'with a QLB-creation utility.
  127.  
  128. 'This program MAY NOT run under
  129. 'the QuickBASIC interpreter.
  130.  
  131. 'Note: The /AH (AH must be in captial letters)
  132. '      option may need to be invoked while compiling
  133. '      and while loading up the QuickBASIC interpreter
  134.  
  135. 'Note: The stacksize must be adjusted for this program
  136. '      run correctly, or it could possibly CRASH the
  137. '      computer.
  138. '      (SEE "CLEAR , , 6144" BELOW)
  139.  
  140. 'slix contains sub-routines that implement tweaked video modes
  141. '(all video modes are unchained/planared with 256 colors)
  142.  
  143. 'There are other modes, but they have not been added in yet.
  144.  
  145. '!!!USE AT YOUR OWN RISK!!!
  146. 'This program may !!!CRASH!!! under certain shells and
  147. 'certain operating systems.  !!!USE AT YOUR OWN RISK!!!
  148.  
  149. 'Note: Some modes may not line up perfectly with certain monitors.
  150. '      The user might have to adjust the size and position of the
  151. '      screen with the monitor's control knobs.
  152.  
  153. 'Note: Some modes may not work on certain monitors and certain VGA
  154. '      cards.  Discoloration may also occur.
  155.  
  156. 'Recommended: 100% VGA compatible card
  157. '             SVGA compatible monitor
  158.  
  159. ' MODE NAME    NUMBER OF PAGES
  160. '256x200x256 = 5.12
  161. '256x224x256 = 4.571428(571428...)
  162. '256x240x256 = 4.26(6...)
  163. '320x200x256 = 4.096
  164. '256x256x256 = 4
  165. '360x200x256 = 3.6408(8...)
  166. '320x240x256 = 3.413(3...)
  167. '360x240x256 = 3.03407(407...)
  168. '360x270x256 = 2.696954732510288...
  169. '376x282x256 = 2.472310245963483...
  170. '256x400x256 = 2.56
  171. '376x308x256 = 2.263608731693838...
  172. '400x300x256 = 2.18453(3...)
  173. '256x480x256 = 2.13(3...)
  174. '320x400x256 = 2.048
  175. '360x360x256 = 2.022716049382716...
  176. '320x480x256 = 1.706(6...)
  177. '360x400x256 = 1.8204(4...)
  178. '360x480x256 = 1.51703(703...)
  179. '376x564x256 = 1.236155122981741...
  180. '400x600x256 = 1.09226(6...)
  181. '
  182. '(x...) = repeating x (only if x is in parentheses)
  183.  
  184. 'Addresses: &H3D4   = base port of the CRT controller (color)
  185. '           &H3C5   = base port of the sequencer
  186. '           &H3CE   = base port of the graphics controller
  187. '           &HA000& = segment of the VGA video memory
  188. '&H = hexdecimal
  189. '& (after &Hxxxx) = used for hexdecimal numbers larger
  190. '                   than 7FFF
  191.  
  192. DECLARE FUNCTION BIN$ (Number&)
  193. DECLARE FUNCTION BIND& (Number$)
  194. DECLARE SUB ClearPage ()
  195. DECLARE SUB COLOUR (DUMMY%)
  196. DECLARE SUB DEMO (Mode$)
  197. DECLARE SUB DrawFrame (SpriteNum%, FrameNum%, XCord%, YCord%)
  198. DECLARE SUB FILEX (filename$, XCord%, YCord%, UseZero%, Center%)
  199. DECLARE SUB FreeObject (ObjectNumber%)
  200. DECLARE FUNCTION GETX% (XCord%, YCord%)
  201. DECLARE SUB GPRINT (DUMMY$)
  202. DECLARE FUNCTION inport$ (Addr&)
  203. DECLARE SUB LoadBG (filename$, headersize%)
  204. DECLARE SUB LoadCharSet ()
  205. DECLARE SUB LoadSprites (filename$, SpriteNum%)
  206. DECLARE SUB memset (Segment&, Addr&, BYTE%, Size&)
  207. DECLARE SUB outport (Addr&, WORD&)
  208. DECLARE SUB PageCopy (FromPage%, ToPage%)
  209. DECLARE SUB PAGEFLIP ()
  210. DECLARE SUB PSETX (XCord%, YCord%, PixelColor%)
  211. DECLARE SUB PUTBG ()
  212. DECLARE SUB PUTX (XCord%, YCord%, xsize%, ysize%, Buffer$, UseZero%)
  213. DECLARE SUB ReadyFrame (Object%, Repeat%, Direction%, SX%, SY%, EX%, EY%)
  214. DECLARE SUB RGBLoad ()
  215. DECLARE SUB RGBSave ()
  216. DECLARE FUNCTION SBR& (BYTE&, Shifter%)
  217. DECLARE FUNCTION SBL& (BYTE&, Shifter%)
  218. DECLARE SUB SetActivePage (PAGE%)
  219. DECLARE SUB SetActiveStart (offset&)
  220. DECLARE SUB SetObject (Object%, Repeat%, Direction%, SX%, SY%, EX%, EY%)
  221. DECLARE SUB SetVisiblePage (PAGE%)
  222. DECLARE SUB SetVisibleStart (offset&)
  223. DECLARE SUB VGA (Mode$)
  224. DECLARE SUB WaitRetrace ()
  225. DECLARE SUB WARNING ()
  226.  
  227. 'Designating global variables
  228. COMMON SHARED slixVERSION%, slixDATE$
  229. COMMON SHARED CursorX%, CursorY%, CurrentColour%
  230. COMMON SHARED VGAWidth%, VGAHeight%, VGAWidthBytes%
  231. COMMON SHARED ActivePage%, VisiblePage%, TotalPages%
  232. COMMON SHARED ActiveStart&, VisibleStart&, ModeName$
  233. COMMON SHARED AfterActiveEnd&, BGOn%
  234. COMMON SHARED BGWidth%, BGHeight%, BGSize&
  235. COMMON SHARED ReservedPage%, UseReservedPage%
  236.  
  237. DEFINT A-Z
  238.  
  239. 'This sets the QuickBASIC stack size
  240. 'at 6144 bytes  It crashed at 4096.
  241. CLEAR , , 6144
  242.  
  243. 'Variable definitions
  244. OPTION BASE 0
  245. DIM SHARED CharSet(0 TO 255, 1 TO 5, 1 TO 5) AS INTEGER
  246.  
  247. 'The following TYPE will use far memory, thus
  248. 'preventing "Out of string space" errors.
  249.  
  250. 'However, errors may still occur.  The only solutions
  251. 'I can think of are 1) load the background from disk
  252. 'everytime, 2) store the background in the video ram
  253. '(onto one of the pages), 3) use EMS functions (INT 67),
  254. '4) allocate conventional memory (INT 21, 48)
  255.  
  256. 'Option 1 is slow, but it is actually faster
  257. 'than loading the background into an TYPED array
  258.  
  259. 'Option 2 is fast, but it wastes one video page
  260.  
  261. 'Option 3 requires more coding
  262.  
  263. 'Option 4 requires more coding as well, possibly
  264. 'using a CALL ABSOLUTE instead of linking the
  265. 'OBJ file in
  266.  
  267. TYPE Custom32K
  268.   Each32K AS STRING * 32767
  269. END TYPE
  270.  
  271. TYPE Custom4K
  272.   Each4K AS STRING * 4096
  273. END TYPE
  274.  
  275. 'While Background0(0 TO 1), Background1(0 TO 1), Background2(0 TO 1), and
  276. 'Background3(0 TO 1), can each hold up to 65534 bytes (not exactly 64K)
  277. 'of data, they may not be used to their full capacity due to the way the
  278. 'PUTX sub-routine was designed.  Plus, a 256K picture will lack 8 bytes
  279. '(since each Custom 32K is one byte off from 32768 bytes).
  280. '
  281. 'Therefore, a slack space is needed.  Background4(0) is the slack
  282. 'space.  4K should be plenty, but if not, change it if necessary.
  283. '
  284. 'A change in the size of Background4(0) may require changing of
  285. 'other parts of the program
  286. '
  287. 'Giving these arrays one dimension saves some memory if the other
  288. 'dimension is not needed.  The program will redim the array if the
  289. 'another dimension is needed.
  290.  
  291. 'While it is extremely slow, the program could use the following
  292. 'background arrays as a simple virtual screen.
  293.  
  294. BGOn% = 0
  295. 'By default, LoadBG & PUTBG are not supported
  296.  
  297. SELECT CASE BGOn%
  298.   CASE IS = 1
  299.     DIM SHARED Background0(0 TO 0) AS Custom32K
  300.     DIM SHARED Background1(0 TO 0) AS Custom32K
  301.     DIM SHARED Background2(0 TO 0) AS Custom32K
  302.     DIM SHARED Background3(0 TO 0) AS Custom32K
  303.     DIM SHARED Background4(0 TO 0) AS Custom4K
  304. END SELECT
  305.  
  306. 'Sprites should not exceed 4K
  307. DIM SHARED Sprite0(0 TO 0) AS Custom4K
  308. DIM SHARED Sprite1(0 TO 0) AS Custom4K
  309. DIM SHARED Sprite2(0 TO 0) AS Custom4K
  310. DIM SHARED Sprite3(0 TO 0) AS Custom4K
  311. DIM SHARED Sprite4(0 TO 0) AS Custom4K
  312. DIM SHARED Sprite5(0 TO 0) AS Custom4K
  313. DIM SHARED Sprite6(0 TO 0) AS Custom4K
  314. DIM SHARED Sprite7(0 TO 0) AS Custom4K
  315. DIM SHARED SpriteWidth(0 TO 7) AS INTEGER
  316. DIM SHARED SpriteHeight(0 TO 7) AS INTEGER
  317. DIM SHARED SpriteLoaded(0 TO 7) AS INTEGER
  318. DIM SHARED MaxSpriteFrame(0 TO 7) AS INTEGER
  319. DIM SHARED Object(0 TO 15) AS INTEGER
  320. DIM SHARED ObjectLock(0 TO 15) AS INTEGER
  321. DIM SHARED ObjectSX(0 TO 15) AS INTEGER
  322. DIM SHARED ObjectEX(0 TO 15) AS INTEGER
  323. DIM SHARED ObjectSY(0 TO 15) AS INTEGER
  324. DIM SHARED ObjectEY(0 TO 15) AS INTEGER
  325. DIM SHARED MaxFrameNumber(0 TO 15) AS INTEGER
  326. DIM SHARED CurrentFrame(0 TO 15) AS INTEGER
  327. DIM SHARED LastFrame(0 TO 15) AS INTEGER
  328. DIM SHARED ObjectRepeat(0 TO 15) AS INTEGER
  329. DIM SHARED ObjectUseCount(0 TO 15) AS INTEGER
  330. DIM SHARED ObjectLastCount(0 TO 15) AS INTEGER
  331.  
  332.  
  333. 'MAIN PROGRAM
  334.  
  335. '.----------------------------.
  336. '| SETS slix's version number |
  337. '`----------------------------'
  338. slixVERSION% = 987
  339.  
  340. '.--------------------------.
  341. '| SETS slix's release date |
  342. '`--------------------------'
  343. slixDATE$ = "August 10, 1996"
  344.  
  345. WARNING 'DO NOT REMOVE THIS UNLESS YOU UNDERSTAND
  346.         'THE CONSEQUENCES
  347.  
  348. DO
  349.   WIDTH 80, 25
  350.   CLS
  351.   COLOR 9, 0
  352.   PRINT " 1) sprite demonstration"
  353.   COLOR 10
  354.   PRINT " 2) picture display (256x200x256)"
  355.   COLOR 11
  356.   PRINT " 3) picture display (256x224x256)"
  357.   COLOR 12
  358.   PRINT " 4) picture display (256x240x256)"
  359.   COLOR 13
  360.   PRINT " 5) picture display (256x400x256)"
  361.   COLOR 14
  362.   PRINT " 6) picture display (256x480x256)"
  363.   COLOR 15
  364.   PRINT " 7) picture display (320x200x256)"
  365.   COLOR 9
  366.   PRINT " 8) picture display (320x240x256)"
  367.   COLOR 10
  368.   PRINT " 9) picture display (320x400x256)"
  369.   COLOR 11
  370.   PRINT "10) picture display (320x480x256)"
  371.   COLOR 12
  372.   PRINT "11) picture display (360x200x256)"
  373.   COLOR 13
  374.   PRINT "12) picture display (360x240x256)"
  375.   COLOR 14
  376.   PRINT "13) picture display (360x270x256)"
  377.   COLOR 15
  378.   PRINT "14) picture display (360x360x256)"
  379.   COLOR 9
  380.   PRINT "15) picture display (360x400x256)"
  381.   COLOR 10
  382.   PRINT "16) picture display (360x480x256)"
  383.   COLOR 11
  384.   PRINT "17) picture display (376x282x256)"
  385.   COLOR 12
  386.   PRINT "18) picture display (376x308x256)"
  387.   COLOR 13
  388.   PRINT "19) picture display (376x564x256)"
  389.   COLOR 14
  390.   PRINT "20) picture display (400x300x256)"
  391.   COLOR 15
  392.   PRINT "21) picture display (400x600x256)"
  393.   COLOR 7
  394.   PRINT "[Q] Quit"
  395.   COLOR 8
  396.   PRINT "[D] Disclaimer"
  397.   COLOR 10
  398.   INPUT "Your Choice:", Selection$
  399.   SELECT CASE UCASE$(Selection$)
  400.     CASE IS = "1"
  401.       VGA "320x200x256"
  402.       SetVisiblePage 1
  403.       SetActivePage 2
  404.       FILEX "320x200.hr8", 0, 0, 0, 0
  405.       'FILEX "320x200.bmp", 0, 0, 0, 0
  406.       'FILEX "320x200.gif", 0, 0, 0, 0
  407.       UseBackground% = 1
  408.       SetVisiblePage 0
  409.       SetActivePage 1
  410.       ReservedPage% = 2
  411.       UseReservedPage% = 1
  412.       LoadSprites "gnoom2.gn2", Object(0)
  413.       LoadSprites "sol07.gn2", Object(1)
  414.       LoadSprites "sol14.gn2", Object(2)
  415.       LoadSprites "ship.gn2", Object(3)
  416.       LoadSprites "slix.gn2", Object(4)
  417.      
  418.       Object(5) = Object(4)
  419.       'The sprite in Object(4) is now shared with Object(5)
  420.      
  421.       ShipNum% = Object(3)
  422.       ShipX% = (VGAWidth% / 2) - (SpriteWidth(ShipNum%) / 2)
  423.       ShipY% = (VGAHeight% / 2) - (SpriteHeight(ShipNum%) / 2)
  424.       ColorCount% = 7
  425.       PrevCursorX% = 0
  426.       PrevCursorY% = 0
  427.       DO
  428.         Keyed$ = INKEY$
  429.         SELECT CASE Keyed$
  430.           CASE "B", "b"
  431.             UseBackground% = (-1) * UseBackground%
  432.           CASE IS = CHR$(0) + CHR$(&H4B)
  433.             ShipX% = ShipX% - ((SpriteWidth(ShipNum%)) / 2)
  434.           CASE IS = CHR$(0) + CHR$(&H4D)
  435.             ShipX% = ShipX% + ((SpriteWidth(ShipNum%)) / 2)
  436.           CASE IS = CHR$(0) + CHR$(&H48)
  437.             ShipY% = ShipY% - ((SpriteHeight(ShipNum%)) / 2)
  438.           CASE IS = CHR$(0) + CHR$(&H50)
  439.             ShipY% = ShipY% + ((SpriteHeight(ShipNum%)) / 2)
  440.         END SELECT
  441.         SELECT CASE ShipX%
  442.           CASE IS < 0
  443.             ShipX% = 0
  444.           CASE IS > (VGAWidth% - SpriteWidth(ShipNum%))
  445.             ShipX% = (VGAWidth% - SpriteWidth(ShipNum%))
  446.         END SELECT
  447.         SELECT CASE ShipY%
  448.           CASE IS < 0
  449.             ShipY% = 0
  450.           CASE IS > (VGAHeight% - SpriteHeight(ShipNum%))
  451.             ShipY% = (VGAHeight% - SpriteHeight(ShipNum%))
  452.         END SELECT
  453.         SELECT CASE UseBackground%
  454.           CASE IS = 1
  455.             PageCopy ReservedPage%, ActivePage%
  456.           CASE ELSE
  457.             ClearPage
  458.         END SELECT
  459.         CursorX% = (((VGAWidth% / 5) / 2) - (44 / 2))
  460.         CursorY% = 0
  461.         COLOUR 255
  462.         GPRINT "USE THE ARROW KEYS"
  463.         COLOUR 254
  464.         GPRINT " (and try pressing [B]...)"
  465.         SetObject 0, 2, 1, 0, ((VGAHeight% - 1) - SpriteHeight(Object(0))), ((VGAWidth% - 1) - SpriteWidth(Object(0))), ((VGAHeight% - 1) - SpriteHeight(Object(0)))
  466.         SetObject 1, 0, 1, ((VGAWidth% - 1) - SpriteWidth(Object(1))), 0, 0, 0
  467.         SetObject 2, 0, 1, ((VGAWidth% - 1) - SpriteWidth(Object(2))), 50, 0, 50
  468.         SetObject ShipNum%, 0, 1, ShipX%, ShipY%, ShipX%, ShipY%
  469.         SetObject 4, 3, 1, ((VGAWidth% - 1) - SpriteWidth(Object(4))), ((VGAHeight% - 1) - SpriteHeight(Object(4))), 0, 0
  470.         SetObject 5, 1, 1, 0, 12, 0, ((VGAHeight% - 1) - SpriteHeight(Object(5)))
  471.         IF PrevCursorX% = ((VGAWidth% / 5) - 20) THEN DirectionX% = -1
  472.         IF PrevCursorX% = 0 THEN DirectionX% = 1
  473.         CursorX% = PrevCursorX% + DirectionX%
  474.         PrevCursorX% = CursorX%
  475.         IF PrevCursorY% = ((VGAHeight% / 5) - 1) THEN DirectionY% = -1
  476.         IF PrevCursorY% = 0 THEN DirectionY% = 1
  477.         CursorY% = PrevCursorY% + DirectionY%
  478.         PrevCursorY% = CursorY%
  479.         ColorCount% = ColorCount% + 8
  480.         IF ColorCount% > 255 THEN ColorCount% = 7
  481.         COLOUR ColorCount%
  482.         GPRINT "Press "
  483.         COLOUR 255
  484.         GPRINT "["
  485.         COLOUR 248
  486.         GPRINT "Q"
  487.         COLOUR 255
  488.         GPRINT "]"
  489.         COLOUR ColorCount%
  490.         GPRINT " to quit..."
  491.         PAGEFLIP
  492.       LOOP UNTIL UCASE$(INKEY$) = "Q"
  493.       UseReservedPage% = 0
  494.       FreeObject 0
  495.       FreeObject 1
  496.       FreeObject 2
  497.       FreeObject 3
  498.       FreeObject 4
  499.       FreeObject 5
  500.     CASE IS = "2"
  501.       DEMO "256x200x256"
  502.     CASE IS = "3"
  503.       DEMO "256x224x256"
  504.     CASE IS = "4"
  505.       DEMO "256x240x256"
  506.     CASE IS = "5"
  507.       DEMO "256x400x256"
  508.     CASE IS = "6"
  509.       DEMO "256x480x256"
  510.     CASE IS = "7"
  511.       DEMO "320x200x256"
  512.     CASE IS = "8"
  513.       DEMO "320x240x256"
  514.     CASE IS = "9"
  515.       DEMO "320x400x256"
  516.     CASE IS = "10"
  517.       DEMO "320x480x256"
  518.     CASE IS = "11"
  519.       DEMO "360x200x256"
  520.     CASE IS = "12"
  521.       DEMO "360x240x256"
  522.     CASE IS = "13"
  523.       DEMO "360x270x256"
  524.     CASE IS = "14"
  525.       DEMO "360x360x256"
  526.     CASE IS = "15"
  527.       DEMO "360x400x256"
  528.     CASE IS = "16"
  529.       DEMO "360x480x256"
  530.     CASE IS = "17"
  531.       DEMO "376x282x256"
  532.     CASE IS = "18"
  533.       DEMO "376x308x256"
  534.     CASE IS = "19"
  535.       DEMO "376x564x256"
  536.     CASE IS = "20"
  537.       DEMO "400x300x256"
  538.     CASE IS = "21"
  539.       DEMO "400x600x256"
  540.     CASE IS = "Q"
  541.       SCREEN 0
  542.       WIDTH 80, 25
  543.       COLOR 7, 0
  544.       CLS
  545.       PRINT "Thanks for testing out slix."
  546.       END
  547.     CASE IS = "D"
  548.       CLS
  549.       COLOR 12
  550.       PRINT "#########################################################"
  551.       PRINT "# DISCLAIMER: USE slix AT YOUR OWN RISK!                #"
  552.       PRINT "#             The author is not liable for any problems #"
  553.       PRINT "#             that may result from the use of slix.     #"
  554.       PRINT "#                                                       #"
  555.       PRINT "#########################################################"
  556.       PRINT
  557.       COLOR 7
  558.       PRINT "Press any key to continue..."
  559.       SLEEP
  560.   END SELECT
  561. LOOP
  562.  
  563. REM $STATIC
  564. FUNCTION BIN$ (Number&)
  565. DO WHILE Number& > 0
  566.   bit% = Number& MOD 2
  567.   Number& = Number& \ 2
  568.   Number$ = RIGHT$(STR$(bit%), 1) + Number$
  569. LOOP
  570. BIN$ = Number$
  571. END FUNCTION
  572.  
  573. 'Limited from 0 to 2,147,483,647 (1111111111111111111111111111111)
  574. FUNCTION BIND& (Number$)
  575. FOR Count% = LEN(Number$) TO 1 STEP -1
  576.   IF MID$(Number$, Count%, 1) = "1" THEN Number& = (Number& + (2 ^ (LEN(Number$) - Count%)))
  577. NEXT Count%
  578. BIND& = Number&
  579. END FUNCTION
  580.  
  581. SUB ClearPage
  582. OUT &H3C4, 2
  583. DEF SEG = &HA000&
  584. PageSize& = ((VGAWidthBytes% * VGAHeight%) - 1)
  585. OUT &H3C5, 1
  586. FOR Count& = 0 TO PageSize&
  587.   POKE Addr& + Count& + ActiveStart&, 0
  588. NEXT Count&
  589. OUT &H3C5, 2
  590. FOR Count& = 0 TO PageSize&
  591.   POKE Addr& + Count& + ActiveStart&, 0
  592. NEXT Count&
  593. OUT &H3C5, 4
  594. FOR Count& = 0 TO PageSize&
  595.   POKE Addr& + Count& + ActiveStart&, 0
  596. NEXT Count&
  597. OUT &H3C5, 8
  598. FOR Count& = 0 TO PageSize&
  599.   POKE Addr& + Count& + ActiveStart&, 0
  600. NEXT Count&
  601. DEF SEG
  602. END SUB
  603.  
  604. SUB COLOUR (DUMMY%)
  605. SELECT CASE DUMMY%
  606.   CASE IS > 255
  607.     DUMMY% = 255
  608.   CASE IS < 0
  609.     DUMMY% = 0
  610. END SELECT
  611. CurrentColour% = DUMMY%
  612. END SUB
  613.  
  614. SUB DEMO (Mode$)
  615. 'Begin demonstration
  616. SecondsWait% = 12
  617. VGA Mode$
  618. SetActivePage 0
  619. CursorX% = 0
  620. CursorY% = 7
  621. COLOUR 232
  622. GPRINT "Please wait..."
  623. GPRINT ""
  624. COLOUR 255
  625. GPRINT "(THIS MESSAGE SHOULD NOT BE ON THE SAME PAGE"
  626. GPRINT ""
  627. COLOUR 232
  628. GPRINT " AS THE PICTURE, UNLESS...)"
  629. GPRINT ""
  630. COLOUR 255
  631. GPRINT "THE PAGE FLIPPING DEMONSTRATION WON'T WORK"
  632. GPRINT ""
  633. COLOUR 232
  634. GPRINT "CORRECTLY ON MODES THAT HAVE LESS THAN 2 PAGES:"
  635. GPRINT ""
  636. COLOUR 255
  637. GPRINT " 320x480x256, 360x400x256, 360x480x256,"
  638. GPRINT ""
  639. COLOUR 232
  640. GPRINT " 376x564x256, 400x600x256)"
  641. GPRINT ""
  642. GPRINT ""
  643. BeginFILEXTimer# = TIMER
  644. SetVisiblePage 0
  645. SetActivePage 1
  646. FILEX "256x200.HR8", 0, 0, 0, 0
  647. EndFILEXTimer# = TIMER
  648. SetVisiblePage 1
  649. CursorX% = 0
  650. CursorY% = 0
  651. COLOUR 7
  652. GPRINT "This is "
  653. COLOUR 255
  654. GPRINT Mode$
  655. COLOUR 7
  656. GPRINT " mode."
  657. GPRINT ""
  658. GPRINT ""
  659. COLOUR 24
  660. GPRINT "The picture is 256 pixels wide,"
  661. GPRINT ""
  662. COLOUR 252
  663. GPRINT "200 pixels long, and has 256 colors"
  664. GPRINT ""
  665. GPRINT ""
  666. COLOUR 71
  667. GPRINT "Press any key to continue...or wait" + STR$(SecondsWait%) + " seconds..."
  668. GPRINT ""
  669. GPRINT ""
  670. SLEEP SecondsWait%
  671. SetVisiblePage 0
  672. SetActivePage 0
  673. CursorX% = 0
  674. CursorY% = 15
  675. COLOUR 154
  676. GPRINT "The FILEX sub-routine took" + STR$(EndFILEXTimer# - BeginFILEXTimer#) + " seconds."
  677. GPRINT ""
  678. GPRINT ""
  679. COLOUR 63
  680. GPRINT STR$(1 / (EndFILEXTimer# - BeginFILEXTimer#))
  681. COLOUR 255
  682. GPRINT " frame(s) per second."
  683. GPRINT ""
  684. COLOUR 17
  685. GPRINT SPACE$(19) + "(for 256x200x256 frames)."
  686. GPRINT ""
  687. GPRINT ""
  688. COLOUR 255
  689. GPRINT "Press any key to continue...or wait" + STR$(SecondsWait%) + " seconds..."
  690. GPRINT ""
  691. GPRINT ""
  692. CursorX% = 0
  693. CursorY% = 7
  694. COLOUR 0
  695. GPRINT STRING$(14, 219)
  696. SetVisiblePage 0
  697. SLEEP SecondsWait%
  698. END SUB
  699.  
  700. SUB DrawFrame (SpriteNum%, FrameNum%, XCord%, YCord%)
  701. SELECT CASE SpriteNum%
  702.   CASE IS = 0
  703.     PUTX XCord%, YCord%, SpriteWidth(SpriteNum%), SpriteHeight(SpriteNum%), Sprite0(FrameNum%).Each4K, 0
  704.   CASE IS = 1
  705.     PUTX XCord%, YCord%, SpriteWidth(SpriteNum%), SpriteHeight(SpriteNum%), Sprite1(FrameNum%).Each4K, 0
  706.   CASE IS = 2
  707.     PUTX XCord%, YCord%, SpriteWidth(SpriteNum%), SpriteHeight(SpriteNum%), Sprite2(FrameNum%).Each4K, 0
  708.   CASE IS = 3
  709.     PUTX XCord%, YCord%, SpriteWidth(SpriteNum%), SpriteHeight(SpriteNum%), Sprite3(FrameNum%).Each4K, 0
  710.   CASE IS = 4
  711.     PUTX XCord%, YCord%, SpriteWidth(SpriteNum%), SpriteHeight(SpriteNum%), Sprite4(FrameNum%).Each4K, 0
  712.   CASE IS = 5
  713.     PUTX XCord%, YCord%, SpriteWidth(SpriteNum%), SpriteHeight(SpriteNum%), Sprite5(FrameNum%).Each4K, 0
  714.   CASE IS = 6
  715.     PUTX XCord%, YCord%, SpriteWidth(SpriteNum%), SpriteHeight(SpriteNum%), Sprite6(FrameNum%).Each4K, 0
  716.   CASE IS = 7
  717.     PUTX XCord%, YCord%, SpriteWidth(SpriteNum%), SpriteHeight(SpriteNum%), Sprite7(FrameNum%).Each4K, 0
  718. END SELECT
  719. END SUB
  720.  
  721. SUB FILEX (filename$, XCord%, YCord%, UseZero%, Center%)
  722.  
  723. RGBPaletteFile% = FREEFILE
  724. PaletteRGB$ = SPACE$(768)
  725. DIM RGBPaletteTranslator(255) AS INTEGER
  726. OPEN "RGB.PAL" FOR BINARY AS #RGBPaletteFile%
  727. GET #RGBPaletteFile%, 1, PaletteRGB$
  728. CLOSE #RGBPaletteFile%
  729.  
  730. FILEXFile% = FREEFILE
  731.  
  732. 'Open file for input so QB stops with an error if it doesn't exist.
  733. OPEN filename$ FOR INPUT AS #FILEXFile%
  734. CLOSE #FILEXFile%
  735.  
  736. OPEN filename$ FOR BINARY AS #FILEXFile%
  737.  
  738. SELECT CASE LOF(FILEXFile%)
  739.   CASE IS > 32
  740.     HeaderTest$ = SPACE$(32)
  741.   CASE ELSE
  742.     HeaderTest$ = SPACE$(LOF(FILEXFile%))
  743. END SELECT
  744.  
  745. GET #FILEXFile%, , HeaderTest$
  746. SELECT CASE LEFT$(HeaderTest$, 3)
  747.   CASE IS = "HR8"
  748.     HeaderSig% = 3
  749.     HeaderSig$ = "HR8"
  750. END SELECT
  751.  
  752. SELECT CASE LEFT$(HeaderTest$, 2)
  753.   CASE IS = "BM"
  754.     HeaderSig% = 2
  755.     HeaderSig$ = "BMPWIN"
  756. END SELECT
  757.  
  758. SELECT CASE LEFT$(HeaderTest$, 3)
  759.   CASE IS = "GIF"
  760.     HeaderSig% = 3
  761.     HeaderSig$ = "GIF"
  762. END SELECT
  763.  
  764. 'HR8 header format:
  765. '
  766. 'Bytes 1, 2, 3   = The characters: "HR8" (without quotes)
  767. 'Bytes 4 and 5   = Horizontal size (signed integer)
  768. 'Bytes 6 and 7   = Vertical size (signed integer)
  769. '
  770. 'note: All numbers are stored in their hexdecimal equivalent.
  771. '      WORDs should not exceed "7FFF", which equals 32767.
  772. '
  773. 'note: All HR8 files contain one byte per color, the RGB palette
  774. '      should be used to view HR8 files.
  775.  
  776. SELECT CASE HeaderSig$
  777.   CASE IS = "HR8"
  778.     HeaderInfo% = 4
  779.     HeaderInfo$ = SPACE$(HeaderInfo%)
  780.     GET #FILEXFile%, HeaderSig% + 1, HeaderInfo$
  781.     headersize% = HeaderSig% + HeaderInfo%
  782.     HR8Width% = ((ASC(MID$(HeaderInfo$, 1, 1)) * 256) + ASC(MID$(HeaderInfo$, 2, 1)))
  783.     HR8Height% = ((ASC(MID$(HeaderInfo$, 3, 1)) * 256) + ASC(MID$(HeaderInfo$, 4, 1)))
  784.     AfterHeader& = CLNG(HR8Width%) * HR8Height%
  785.     BufferSize% = (32767 - (32767 MOD HR8Width%))
  786.     Buffer$ = SPACE$(BufferSize%)
  787.     'Centering disregards the XCord%
  788.     'and YCord% values specified
  789.     SELECT CASE Center%
  790.       CASE IS = 1
  791.         XCord% = ABS((VGAWidth% - HR8Width%) / 2)
  792.         YCord% = ABS((VGAHeight% - HR8Height%) / 2)
  793.     END SELECT
  794.     DO
  795.       GET #FILEXFile%, , Buffer$
  796.       Counter& = (LEN(Buffer$) + Counter&)
  797.       SELECT CASE Counter&
  798.         CASE IS > AfterHeader&
  799.           Counter& = (Counter& - (Counter& MOD AfterHeader&))
  800.       END SELECT
  801.       PUTX (XCord% + (Counter& MOD HR8Width%)), (YCord% + ((OldCounter&) / HR8Width%)), HR8Width%, (LEN(Buffer$) / HR8Width%), Buffer$, UseZero%
  802.       OldCounter& = Counter&
  803.     LOOP UNTIL EOF(FILEXFile%)
  804.   CASE IS = "BMPWIN"
  805.     header$ = SPACE$(14)
  806.     sizing$ = SPACE$(4)
  807.     GET #FILEXFile%, 1, header$
  808.     GET #FILEXFile%, 15, sizing$
  809.     bmpinfosize = CVI(sizing$)
  810.     'bmpinfosize - Is the size of the information header for the bitmap.
  811.     '              Different bitmap versions have variations in filetypes.
  812.     '              40 is a standard windows 3.1 bitmap.
  813.     '              12 is for OS/2 bitmaps
  814.     'The next routine reads in the appropriate headers and colour tables.
  815.     'nbits is the number of bits per pixel - i.e. number of colours
  816.     '1 bit = 2 colours, 4 bits = 16 colours, 8 bits = 256 colours, etc.
  817.     'the 24 bit mode does not have a palette, its colours are expressed as
  818.     'image data
  819.  
  820.     'Design of a windows 3.1 bitmap - Taken from bmp.zip on the
  821.     'x2ftp.oulu.fi ftp site under /pub/msdos/programming/formats
  822.     'Specifications for a Windows 3.1 bitmap. (.BMP)
  823.     'Email any questions/responses to me at zabudsk@ecf.utoronto.ca
  824.     'or post to alt.lang.basic or comp.lang.basic.misc.
  825.  
  826.     '       | # of   |
  827.     'Offset | bytes  | Function (value)
  828.     '-------+--------+--- General Picture information starts here---------
  829.     '  0    |   2    | (BM) - Tells us that the picture is in bmp format
  830.     '  2    |   4    | Size of the file (without header?)
  831.     '  6    |   2    | (0) Reserved1 - Must be zero
  832.     '  8    |   2    | (0) Reserved2 - Must be zero
  833.     '  10   |   4    | Number of bytes offset of the picture data
  834.     '-------+--------+--- Information Header starts here -----------------
  835.     '  14   |   4    | (40/12) Size of information header (Win3.1/OS2)
  836.     '  18   |   4    | Picture width in pixels
  837.     '  22   |   4    | Picture Height in pixels
  838.     '  26   |   2    | (1) Number of planes, must be 1
  839.     '  28   |   2    | Number of bits per pixel (bpp), must be 1,4,8 or 24
  840.     '  30   |   4    | (0) Compression - 0 means no compression, 1,2 are RLEs
  841.     '  34   |   4    | Image size in bytes
  842.     '  38   |   4    | picture width in pels per metre
  843.     '  42   |   4    | picture height in pels per metre
  844.     '  46   |   4    | (0) Number of colours used in the picture, 0 means all
  845.     '  50   |   4    | (0) Number of important colours, 0 means all
  846.     '-------+--------+--- Palette data starts here -----------------------
  847.     '  54   |   1    | (b) - blue intensity component, color 0 - range 0 to 255
  848.     '  55   |   1    | (g) - green intensity component, color 0 - range 0 to 255
  849.     '  56   |   1    | (r) - red intensity component, color 0 - range 0 to 255
  850.     '  57   |   1    | (0) - unused
  851.     '  58   |   1    | (b) - blue intensity component, color 0 - range 0 to 255
  852.     '  ...  | ...    |
  853.     '  54   | 4*2^bpp| total range of palette
  854.     '-------+--------+--- Image data starts here -------------------------
  855.     '54+    | width* | Bitmap data starting at lower left portion of the
  856.     '(4*2^n)| height*| image moving from left towards right. Moving up 1
  857.     '       | (8/bpp)| pixel when at the right hand side of the image, starting
  858.     '       |        | from the left side again, until the top right of the
  859.     '       |        | image is reached
  860.  
  861.     'Note that this format is slightly different for a OS/2 Bitmap.
  862.     'The header is the same up to (but not including) bit 30-
  863.     'The palette colour values follow at bit 30, with the form...
  864.     '1 byte blue intensity
  865.     '1 byte green intensity
  866.     '1 byte red intensity
  867.     'For each colour of the picture.
  868.     'Bitmapped image data follows the colour tables
  869.  
  870.  
  871.     'Special note: When storing 1 bit (2 colour) pictures.
  872.     '8 horizontal pixels are packed into 1 byte. Each bit determines
  873.     'the colour of one pixel (colour 0 or colour 1)
  874.  
  875.     '4 bit pictures (16 colours) use 2 nibbles (4 bits) for each pixel
  876.     'thus there are 2 pixels for each byte of image data.
  877.  
  878.     '8 bit pictures use 1 byte per pixel. Each byte of image data
  879.     'represents one of 256 colours.
  880.  
  881.     '24 bit pictures express colour values by using 3 bytes and each has a
  882.     'value between 0 and 255. The first byte is for red, the second is for
  883.     'green and the third is for blue. Thus (256)^3 or 2^24 of 16777216 different
  884.     'colours.
  885.  
  886.     IF bmpinfosize = 12 THEN
  887.        infoheader$ = SPACE$(12)
  888.        GET #FILEXFile%, 15, infoheader$
  889.        nbits = CVI(MID$(infoheader$, 15, 4))
  890.  
  891.        IF nbits = 1 THEN
  892.           palet$ = SPACE$(6)
  893.           GET #FILEXFile%, bmpinfosize + 15, palet$
  894.        ELSEIF nbits = 4 THEN
  895.           palet$ = SPACE$(48)
  896.           GET #FILEXFile%, bmpinfosize + 15, palet$
  897.        ELSEIF nbits = 8 THEN
  898.           palet$ = SPACE$(768)
  899.           GET #FILEXFile%, bmpinfosize + 15, palet$
  900.        END IF
  901.     ELSEIF bmpinfosize = 40 THEN
  902.        infoheader$ = SPACE$(40)
  903.        GET #FILEXFile%, 15, infoheader$
  904.        nbits = CVI(MID$(infoheader$, 15, 4))
  905.        IF nbits = 1 THEN
  906.           palet$ = SPACE$(8)
  907.           GET #FILEXFile%, bmpinfosize + 15, palet$
  908.        ELSEIF nbits = 4 THEN
  909.           palet$ = SPACE$(64)
  910.           GET #FILEXFile%, bmpinfosize + 15, palet$
  911.        ELSEIF nbits = 8 THEN
  912.           palet$ = SPACE$(1024)
  913.           GET #FILEXFile%, bmpinfosize + 15, palet$
  914.        END IF
  915.     END IF
  916.     
  917.  
  918.     ft$ = MID$(header$, 1, 2)
  919.     'PRINT "Type of file (Should be BM): "; ft$
  920.  
  921.     filesize& = CVL(MID$(header$, 3, 4))
  922.     'PRINT "Size of file: "; filesize&
  923.  
  924.     r1 = CVI(MID$(header$, 7, 2))
  925.     'PRINT "Reserved 1: "; r1
  926.  
  927.     r2 = CVI(MID$(header$, 9, 2))
  928.     'PRINT "Reserved 2: "; r2
  929.  
  930.     offset = CVL(MID$(header$, 11, 4))
  931.     'PRINT "Number of bytes offset from beginning: "; offset
  932.  
  933.     'PRINT
  934.  
  935.     headersize = CVL(MID$(infoheader$, 1, 4))
  936.     'PRINT "Size of header: "; headersize
  937.  
  938.     picwidth = CVL(MID$(infoheader$, 5, 4))
  939.     'PRINT "Width: "; picwidth
  940.  
  941.     picheight = CVL(MID$(infoheader$, 9, 4))
  942.     'PRINT "Height: "; picheight
  943.  
  944.     nplanes = CVI(MID$(infoheader$, 13, 4))
  945.     'PRINT "Planes: "; nplanes
  946.  
  947.     'PRINT "Bits per plane: "; nbits
  948.  
  949.     'PRINT
  950.  
  951.     IF headersize = 40 THEN
  952.        'PRINT "Compression: ";
  953.        comptype = CVL(MID$(infoheader$, 17, 4))
  954.        'IF comptype = 0 THEN PRINT "None"
  955.        'IF comptype = 1 THEN PRINT "Run Length - 8 Bits"
  956.        'IF comptype = 2 THEN PRINT "Run Length - 4 Bits"
  957.  
  958.        imagesize& = CVL(MID$(infoheader$, 21, 4))
  959.        'PRINT "Image Size (bytes): "; imagesize&
  960.  
  961.        xsize = CVL(MID$(infoheader$, 25, 4))
  962.        'PRINT "X size (pixels per metre): "; xsize
  963.  
  964.        ysize = CVL(MID$(infoheader$, 29, 4))
  965.        'PRINT "Y size (pixels per metre): "; ysize
  966.  
  967.        colorsused = CVL(MID$(infoheader$, 33, 4))
  968.        'PRINT "Number of colours used: "; colorsused
  969.  
  970.        neededcolours = CVL(MID$(infoheader$, 37, 4))
  971.        'PRINT "Number of important colours: "; neededcolours
  972.     END IF
  973.     'PRINT
  974.     'PRINT "Press Any key to continue."
  975.     'WHILE INKEY$ = ""
  976.     'WEND
  977.  
  978.     IF nbits = 1 THEN
  979.        'SCREEN 11
  980.     ELSEIF nbits = 4 THEN
  981.        'SCREEN 12
  982.     ELSEIF nbits = 8 OR nbits = 24 THEN
  983.        'SCREEN 13
  984.     END IF
  985.     IF bmpinfosize = 40 THEN ngroups = 4
  986.     IF bmpinfosize = 12 THEN ngroups = 3
  987.  
  988.     IF nbits = 24 THEN
  989.        IF ngroups = 3 THEN
  990.           FOR c = 0 TO 63
  991.              d = c * 4
  992.              palet$ = palet$ + CHR$(d) + CHR$(d) + CHR$(d)
  993.              palet$ = palet$ + CHR$(d) + CHR$(d) + CHR$(d + 1)
  994.              palet$ = palet$ + CHR$(d) + CHR$(d + 1) + CHR$(d)
  995.              palet$ = palet$ + CHR$(d + 1) + CHR$(d) + CHR$(d)
  996.           NEXT c
  997.        ELSEIF ngroups = 4 THEN
  998.           FOR c = 0 TO 63
  999.              d = c * 4
  1000.              palet$ = palet$ + CHR$(d) + CHR$(d) + CHR$(d) + CHR$(0)
  1001.              palet$ = palet$ + CHR$(d) + CHR$(d) + CHR$(d + 1) + CHR$(0)
  1002.              palet$ = palet$ + CHR$(d) + CHR$(d + 1) + CHR$(d) + CHR$(0)
  1003.              palet$ = palet$ + CHR$(d + 1) + CHR$(d) + CHR$(d) + CHR$(0)
  1004.           NEXT c
  1005.        END IF
  1006.     END IF
  1007.  
  1008.     FOR X = 1 TO LEN(palet$) STEP ngroups
  1009.        zb# = INT((ASC(MID$(palet$, X, 1))) / 4)
  1010.        zg# = INT((ASC(MID$(palet$, X + 1, 1))) / 4)
  1011.        zr# = INT((ASC(MID$(palet$, X + 2, 1))) / 4)
  1012.        Blue% = zb# \ (36 / 4)
  1013.        Green% = zg# \ (84 / 4)
  1014.        Red% = zr# \ (36 / 4)
  1015.        FOR Count% = 0 TO 255
  1016.          SELECT CASE (ASC(MID$(PaletteRGB$, ((Count% * 3) + 1), 1)) \ 36)
  1017.            CASE IS = Red%
  1018.              SELECT CASE (ASC(MID$(PaletteRGB$, ((Count% * 3) + 2), 1)) \ 84)
  1019.                CASE IS = Green%
  1020.                  SELECT CASE (ASC(MID$(PaletteRGB$, ((Count% * 3) + 3), 1)) \ 36)
  1021.                    CASE IS = Blue%
  1022.                      RGBPaletteTranslator((X - 1) / ngroups) = Count%
  1023.                  END SELECT
  1024.              END SELECT
  1025.          END SELECT
  1026.        NEXT Count%
  1027.        zc# = zb# * 65536# + zg# * 256# + zr#
  1028.        cres = ASC(MID$(palet$, X + 3, 1))
  1029.        'PALETTE ((x - 1) / ngroups), zc#
  1030.     NEXT X
  1031.  
  1032.     IF nbits = 24 THEN
  1033.        y = picheight - 1
  1034.        X = 0
  1035.        dat$ = "   "
  1036.        WHILE y >= 0
  1037.           WHILE X < picwidth
  1038.              GET 1, , dat$
  1039.              p1 = INT((ASC(MID$(dat$, 1, 1)) + ASC(MID$(dat$, 1, 1)) + ASC(MID$(dat$, 1, 1))) / 3)
  1040.              IF X < VGAWidth% AND y < VGAHeight% THEN PSETX X, y, RGBPaletteTranslator(p1)
  1041.              X = X + 1
  1042.           WEND
  1043.           y = y - 1
  1044.           X = 0
  1045.        WEND
  1046.     ELSEIF nbits = 8 THEN
  1047.        y = picheight - 1
  1048.        X = 0
  1049.        dat$ = " "
  1050.        WHILE y >= 0
  1051.           WHILE X < picwidth
  1052.              GET 1, , dat$
  1053.              IF X < VGAWidth% AND y < VGAHeight% THEN PSETX X, y, RGBPaletteTranslator(ASC(dat$))
  1054.              X = X + 1
  1055.           WEND
  1056.           y = y - 1
  1057.           X = 0
  1058.        WEND
  1059.     ELSEIF nbits = 4 THEN
  1060.        y = picheight - 1
  1061.        X = 0
  1062.        dat$ = " "
  1063.        WHILE y >= 0
  1064.           WHILE X < picwidth
  1065.             GET 1, , dat$
  1066.             LOCATE 1, 1
  1067.             p1 = ASC(dat$) AND 15
  1068.             p2 = ASC(dat$) AND 240 / 16
  1069.             IF X < VGAWidth% AND y < VGAHeight% THEN PSETX X, y, RGBPaletteTranslator(p1)
  1070.             IF X < VGAWidth% AND y < VGAHeight% THEN PSETX X + 1, y, RGBPaletteTranslator(p2)
  1071.             X = X + 2
  1072.           WEND
  1073.           y = y - 1
  1074.           X = 0
  1075.        WEND
  1076.     ELSEIF nbits = 1 THEN
  1077.        y = picheight - 1
  1078.        X = 0
  1079.        dat$ = " "
  1080.        WHILE y >= 0
  1081.           WHILE X < picwidth
  1082.             GET 1, , dat$
  1083.             FOR P = 0 TO 7
  1084.                IF X < VGAWidth% AND y < VGAHeight% THEN PSETX X + (7 - P), y, RGBPaletteTranslator((p1 AND 2 ^ P) / 2 ^ P)
  1085.                NEXT P
  1086.             X = X + 8
  1087.           WEND
  1088.           y = y - 1
  1089.           X = 0
  1090.        WEND
  1091.     END IF
  1092.  
  1093.     'CLOSE
  1094.   CASE IS = "GIF"
  1095.     '
  1096.     'DEGIF6.BAS - No frills GIF decoder for the VGA's 320x200x256 mode.
  1097.     'By Rich Geldreich 1993 (Public domain, use as you wish.)
  1098.     'This version should properly decode all LZW encoded images in
  1099.     'GIF image files. I've finally added GIF89a and local colormap
  1100.     'support, so it more closely follows the GIF specification. It
  1101.     'still doesn't support the entire GIF89a specification, but it'll
  1102.     'show most GIF files fine.
  1103.     'The GIF decoding speed of this program isn't great, but I'd say
  1104.     'for an all QB/PDS decoder it's not bad!
  1105.     'Note: This program does not stop decoding the GIF image after the
  1106.     'rest of the scanlines become invisible! This happens with images
  1107.     'larger than the 320x200 screen. So if the program seems to be
  1108.     'just sitting there, accessing your hard disk, don't worry...
  1109.     'It'll beep when it's done.
  1110.     'DEFINT A-Z
  1111.     'Prefix() and Suffix() hold the LZW phrase dictionary.
  1112.     'OutStack() is used as a decoding stack.
  1113.     'ShiftOut() as a power of two table used to quickly retrieve the LZW
  1114.     'multibit codes.
  1115.     DIM Prefix(4095), Suffix(4095), OutStack(4095), ShiftOut(8)
  1116.  
  1117.     'The following line is for the QB environment(slow).
  1118.     DIM YBase AS LONG, Powersof2(11) AS LONG, WorkCode AS LONG
  1119.     'For a little more speed, unremark the next line and remark the one
  1120.     'above, before you compile... You'll get an overflow error if the
  1121.     'following line is used in the QB environment, so change it back.
  1122.     'DIM YBase AS INTEGER, Powersof2(11) AS INTEGER, WorkCode AS INTEGER
  1123.  
  1124.     'Precalculate power of two tables for fast shifts.
  1125.     FOR a = 0 TO 8: ShiftOut(8 - a) = 2 ^ a: NEXT
  1126.     FOR a = 0 TO 11: Powersof2(a) = 2 ^ a: NEXT
  1127.  
  1128.     'Get GIF filename.
  1129.     'A$ = COMMAND$: IF A$ = "" THEN INPUT "GIF file"; A$: IF A$ = "" THEN END
  1130.     'Add GIF extension if the given filename doesn't have one.
  1131.     'FOR A = LEN(filename$) TO 1 STEP -1
  1132.     'SELECT CASE MID$(filename$, A, 1)
  1133.         'CASE "\", ":": EXIT FOR
  1134.         'CASE ".": Extension = -1: EXIT FOR
  1135.         'END SELECT
  1136.     'NEXT
  1137.     'IF Extension = 0 THEN filename$ = filename$ + ".GIF"
  1138.  
  1139.     'Open file for input so QB stops with an error if it doesn't exist.
  1140.     'OPEN A$ FOR INPUT AS #FILEXFile%: CLOSE #FILEXFile%
  1141.     'OPEN A$ FOR BINARY AS #FILEXFile%
  1142.  
  1143.     'Check to see if GIF file. Ignore GIF version number.
  1144.     a$ = "      ": GET #FILEXFile%, 1, a$
  1145.     'IF LEFT$(A$, 3) <> "GIF" THEN PRINT "Not a GIF file.": END
  1146.  
  1147.     'Get logical screen's X and Y resolution.
  1148.     GET #FILEXFile%, , TotalX: GET #FILEXFile%, , TotalY: GOSUB GetByte
  1149.     'Calculate number of colors and find out if a global palette exists.
  1150.     NumColors = 2 ^ ((a AND 7) + 1): NoPalette = (a AND 128) = 0
  1151.     'Retrieve background color.
  1152.     GOSUB GetByte: Background = a
  1153.  
  1154.     'Get aspect ratio and ignore it.
  1155.     GOSUB GetByte
  1156.  
  1157.     'Retrieve global palette if it exists.
  1158.     IF NoPalette = 0 THEN P$ = SPACE$(NumColors * 3): GET #FILEXFile%, , P$
  1159.  
  1160.     DO 'Image decode loop
  1161.  
  1162.     'Skip by any GIF extensions.
  1163.     '(With a few modifications this code could also fetch comments.)
  1164.     DO
  1165.         'Skip by any zeros at end of image (why must I do this? the
  1166.         'GIF spec never mentioned it)
  1167.         DO
  1168.             IF EOF(FILEXFile%) THEN GOTO AllDone 'if at end of file, exit
  1169.             GOSUB GetByte
  1170.         LOOP WHILE a = 0           'loop while byte fetched is zero
  1171.  
  1172.         SELECT CASE a
  1173.         CASE 44  'We've found an image descriptor!
  1174.             EXIT DO
  1175.         CASE 59  'GIF trailer, stop decoding.
  1176.             GOTO AllDone
  1177.         CASE IS <> 33
  1178.             'PRINT "Unknown GIF extension type."': END
  1179.         END SELECT
  1180.         'Skip by blocked extension data.
  1181.         GOSUB GetByte
  1182.         DO: GOSUB GetByte: a$ = SPACE$(a): GET #FILEXFile%, , a$: LOOP UNTIL a = 0
  1183.     LOOP
  1184.     'Get image's start coordinates and size.
  1185.     GET #FILEXFile%, , XStart: GET #FILEXFile%, , YStart: GET #FILEXFile%, , XLength: GET #FILEXFile%, , YLength
  1186.     XEnd = XStart + XLength: YEnd = YStart + YLength
  1187.  
  1188.     'Check for local colormap, and fetch it if it exists.
  1189.     GOSUB GetByte
  1190.     IF (a AND 128) THEN
  1191.         NoPalette = 0
  1192.         NumColors = 2 ^ ((a AND 7) + 1)
  1193.         P$ = SPACE$(NumColors * 3): GET #FILEXFile%, , P$
  1194.     END IF
  1195.  
  1196.     'Check for interlaced image.
  1197.     Interlaced = (a AND 64) > 0: PassNumber = 0: PassStep = 8
  1198.  
  1199.     'Get LZW starting code size.
  1200.     GOSUB GetByte
  1201.  
  1202.     'Calculate clear code, end of stream code, and first free LZW code.
  1203.     ClearCode = 2 ^ a
  1204.     EOSCode = ClearCode + 1
  1205.     FirstCode = ClearCode + 2: NextCode = FirstCode
  1206.     StartCodeSize = a + 1: CodeSize = StartCodeSize
  1207.  
  1208.     'Find maximum code for the current code size.
  1209.     StartMaxCode = 2 ^ (a + 1) - 1: MaxCode = StartMaxCode
  1210.  
  1211.     BitsIn = 0: BlockSize = 0: BlockPointer = 1
  1212.  
  1213.     X = XStart: y = YStart: YBase = y * CLNG(VGAWidth%)
  1214.  
  1215.     'Set screen 13 in not set yet.
  1216.     IF FirstTime = 0 THEN
  1217.         'Go to VGA mode 13 (320x200x256).
  1218.         'SCREEN 13: DEF SEG = &HA000
  1219.     END IF
  1220.  
  1221.     'Set palette, if there was one.
  1222.     IF NoPalette = 0 THEN
  1223.         'Use OUTs for speed.
  1224.         'OUT &H3C8, 0
  1225.         'FOR A = 1 TO NumColors * 3: OUT &H3C9, ASC(MID$(P$, A, 1)) \ 4: NEXT
  1226.         FOR a% = 0 TO (NumColors - 1)
  1227.           Blue% = ASC(MID$(P$, (a * 3) + 1, 1)) \ 36
  1228.           Green% = ASC(MID$(P$, (a * 3) + 2, 1)) \ 84
  1229.           Red% = ASC(MID$(P$, (a * 3) + 3, 1)) \ 36
  1230.           FOR Count% = 0 TO 255
  1231.             SELECT CASE (ASC(MID$(PaletteRGB$, ((Count% * 3) + 1), 1)) \ 36)
  1232.               CASE IS = Blue%
  1233.                 SELECT CASE (ASC(MID$(PaletteRGB$, ((Count% * 3) + 2), 1)) \ 84)
  1234.                   CASE IS = Green%
  1235.                     SELECT CASE (ASC(MID$(PaletteRGB$, ((Count% * 3) + 3), 1)) \ 36)
  1236.                       CASE IS = Red%
  1237.                         RGBPaletteTranslator(a%) = Count%
  1238.                     END SELECT
  1239.                 END SELECT
  1240.             END SELECT
  1241.           NEXT Count%
  1242.         NEXT a%
  1243.         'Save palette of image to disk.
  1244.         'OPEN "pal." FOR BINARY AS #2: PUT #2, , P$: CLOSE #2
  1245.     END IF
  1246.  
  1247.     'IF FirstTime = 0 THEN
  1248.       'Clear entire screen to background color. This isn't
  1249.       'done until the image's palette is set, to avoid flicker
  1250.       'on some GIFs.
  1251.         'LINE (0, 0)-(319, 199), Background, BF
  1252.         'FirstTime = -1
  1253.     'END IF
  1254.  
  1255.     'Decode LZW data stream to screen.
  1256.     DO
  1257.         'Retrieve one LZW code.
  1258.         GOSUB GetCode
  1259.         'Is it an end of stream code?
  1260.         IF Code <> EOSCode THEN
  1261.             'Is it a clear code? (The clear code resets the sliding
  1262.             'dictionary - it *should* be the first LZW code present in
  1263.             'the data stream.)
  1264.             IF Code = ClearCode THEN
  1265.                 NextCode = FirstCode
  1266.                 CodeSize = StartCodeSize
  1267.                 MaxCode = StartMaxCode
  1268.                 DO: GOSUB GetCode: LOOP WHILE Code = ClearCode
  1269.                 IF Code = EOSCode THEN GOTO ImageDone
  1270.                 LastCode = Code: LastPixel = Code
  1271.                 'IF X < 320 AND y < 200 THEN POKE X + YBase, LastPixel
  1272.                 'IF x < VGAWidth% AND y < VGAHeight% THEN PSETX x, y, LastPixel
  1273.                 IF X < VGAWidth% AND y < VGAHeight% THEN PSETX X, y, RGBPaletteTranslator(LastPixel)
  1274.                 X = X + 1: IF X = XEnd THEN GOSUB NextScanLine
  1275.             ELSE
  1276.                 CurCode = Code: StackPointer = 0
  1277.  
  1278.                 'Have we entered this code into the dictionary yet?
  1279.                 IF Code >= NextCode THEN
  1280.                     IF Code > NextCode THEN GOTO AllDone 'Bad GIF if this happens.
  1281.                    'mimick last code if we haven't entered the requested
  1282.                    'code into the dictionary yet
  1283.                     CurCode = LastCode
  1284.                     OutStack(StackPointer) = LastPixel
  1285.                     StackPointer = StackPointer + 1
  1286.                 END IF
  1287.  
  1288.                 'Recursively get each character of the string.
  1289.                 'Since we get the characters in reverse, "push" them
  1290.                 'onto a stack so we can "pop" them off later.
  1291.                 'Hint: There is another, much faster way to accomplish
  1292.                 'this that doesn't involve a decoding stack at all...
  1293.                 DO WHILE CurCode >= FirstCode
  1294.                     OutStack(StackPointer) = Suffix(CurCode)
  1295.                     StackPointer = StackPointer + 1
  1296.                     CurCode = Prefix(CurCode)
  1297.                 LOOP
  1298.  
  1299.                 LastPixel = CurCode
  1300.                 'IF X < 320 AND y < 200 THEN POKE X + YBase, LastPixel
  1301.                 'IF x < VGAWidth% AND y < VGAHeight% THEN PSETX x, y, LastPixel
  1302.                 IF X < VGAWidth% AND y < VGAHeight% THEN PSETX X, y, RGBPaletteTranslator(LastPixel)
  1303.                 X = X + 1: IF X = XEnd THEN GOSUB NextScanLine
  1304.  
  1305.                 '"Pop" each character onto the display.
  1306.                 FOR a = StackPointer - 1 TO 0 STEP -1
  1307.                     'IF X < 320 AND y < 200 THEN POKE X + YBase, OutStack(A)
  1308.                     'IF x < VGAWidth% AND y < VGAHeight% THEN PSETX x, y, OutStack(A)
  1309.                     IF X < VGAWidth% AND y < VGAHeight% THEN PSETX X, y, RGBPaletteTranslator(OutStack(a))
  1310.                     X = X + 1: IF X = XEnd THEN GOSUB NextScanLine
  1311.                 NEXT
  1312.  
  1313.                 'Can we put this new string into our dictionary? (Some GIF
  1314.                 'encoders will wait a bit when the dictionary is full
  1315.                 'before sending a clear code- this increases compression
  1316.                 'because the dictionary's contents are thrown away less
  1317.                 'often.)
  1318.                 IF NextCode < 4096 THEN
  1319.                     'Store new string in the dictionary for later use.
  1320.                     Prefix(NextCode) = LastCode
  1321.                     Suffix(NextCode) = LastPixel
  1322.                     NextCode = NextCode + 1
  1323.                     'Time to increase the LZW code size?
  1324.                     IF (NextCode > MaxCode) AND (CodeSize < 12) THEN
  1325.                         CodeSize = CodeSize + 1
  1326.                         MaxCode = MaxCode * 2 + 1
  1327.                     END IF
  1328.                 END IF
  1329.                 LastCode = Code
  1330.             END IF
  1331.         END IF
  1332.     LOOP UNTIL Code = EOSCode
  1333. ImageDone:
  1334.  
  1335.     LOOP
  1336.  
  1337. AllDone:
  1338.  
  1339.     'Save image and palette to BSAVE file.
  1340.     'DEF SEG = &HA000
  1341.     'OUT &H3C7, 0
  1342.     'FOR a = 0 TO 767
  1343.     '    POKE a + 64000, INP(&H3C9)
  1344.     'NEXT
  1345.     'BSAVE "pic.bas", 0, 64768
  1346.  
  1347.     'Load images saved with the above code with this:
  1348.     'DEF SEG= &HA000
  1349.     'BLOAD "Pic.Bas"
  1350.     'OUT &H3C8, 0
  1351.     'FOR a = 0 To 767
  1352.     '     OUT &H3C9, Peek(a+ 64000)
  1353.     'NEXT
  1354.  
  1355.     'BEEP: DO: LOOP WHILE INKEY$ <> "": DO: LOOP UNTIL INKEY$ <> ""
  1356.     'END
  1357.     GOTO EndGIFRoutine 'Yes, I know...This is poorly structured programming
  1358.  
  1359.  
  1360.     'Slowly reads one byte from the GIF file...
  1361. GetByte: a$ = " ": GET #FILEXFile%, , a$: a = ASC(a$): RETURN
  1362.  
  1363.     'Moves down one scanline. If the GIF is interlaced, then the number
  1364.     'of scanlines skipped is based on the current pass.
  1365. NextScanLine:
  1366.         IF Interlaced THEN
  1367.             y = y + PassStep
  1368.             IF y >= YEnd THEN
  1369.                 PassNumber = PassNumber + 1
  1370.                 SELECT CASE PassNumber
  1371.                 CASE 1: y = 4: PassStep = 8
  1372.                 CASE 2: y = 2: PassStep = 4
  1373.                 CASE 3: y = 1: PassStep = 2
  1374.                 END SELECT
  1375.             END IF
  1376.         ELSE
  1377.             y = y + 1
  1378.         END IF
  1379.         X = XStart: YBase = y * CLNG(VGAWidth%)
  1380.     RETURN
  1381.  
  1382.     'Reads a multibit code from the data stream.
  1383. GetCode:
  1384.         WorkCode = LastChar \ ShiftOut(BitsIn)
  1385.       'Loop while more bits are needed.
  1386.         DO WHILE CodeSize > BitsIn
  1387.     'Reads a byte from the LZW data stream. Since the data stream is
  1388.     'blocked, a check is performed for the end of the current block
  1389.     'before each byte is fetched.
  1390.             IF BlockPointer > BlockSize THEN
  1391.               'Retrieve block's length
  1392.                 GOSUB GetByte: BlockSize = a
  1393.                 a$ = SPACE$(BlockSize): GET #FILEXFile%, , a$
  1394.                 BlockPointer = 1
  1395.             END IF
  1396.           'Yuck, ASC() and MID$() aren't that fast.
  1397.             LastChar = ASC(MID$(a$, BlockPointer, 1))
  1398.             BlockPointer = BlockPointer + 1
  1399.           'Append 8 more bits to the input buffer
  1400.             WorkCode = WorkCode OR LastChar * Powersof2(BitsIn)
  1401.             BitsIn = BitsIn + 8
  1402.         LOOP
  1403.       'Take away x number of bits.
  1404.         BitsIn = BitsIn - CodeSize
  1405.       'Return code to caller.
  1406.         Code = WorkCode AND MaxCode
  1407.     RETURN
  1408. EndGIFRoutine:
  1409.   CASE ELSE
  1410.     'Assume the file is in RAW format
  1411.     AfterHeader& = CLNG(VGAWidth%) * VGAHeight%
  1412.     SELECT CASE AfterHeader&
  1413.       CASE IS > LOF(FILEXFile%)
  1414.         AfterHeader& = FILEXFile%
  1415.     END SELECT
  1416.     BufferSize% = (32767 - (32767 MOD VGAWidth%))
  1417.     Buffer$ = SPACE$(BufferSize%)
  1418.     'Centering disregards the XCord%
  1419.     'and YCord% values specified
  1420.     DO
  1421.       GET #FILEXFile%, , Buffer$
  1422.       Counter& = (LEN(Buffer$) + Counter&)
  1423.       SELECT CASE Counter&
  1424.         CASE IS > AfterHeader&
  1425.           Counter& = (Counter& - (Counter& MOD AfterHeader&))
  1426.       END SELECT
  1427.       PUTX (XCord% + (Counter& MOD VGAWidth%)), (YCord% + ((OldCounter&) / VGAWidth%)), VGAWidth%, (LEN(Buffer$) / VGAWidth%), Buffer$, UseZero%
  1428.       OldCounter& = Counter&
  1429.     LOOP UNTIL EOF(FILEXFile%)
  1430. END SELECT
  1431. CLOSE #FILEXFile%
  1432. END SUB
  1433.  
  1434. SUB FreeObject (ObjectNumber%)
  1435. ObjectLock(ObjectNumber%) = 0
  1436. FOR Count% = 0 TO 15
  1437.   SELECT CASE Object(Count%)
  1438.     CASE IS = Object(ObjectNumber%)
  1439.       SELECT CASE ObjectLock(Count%)
  1440.         CASE IS = 1
  1441.           PreserveSprite% = 1
  1442.       END SELECT
  1443.   END SELECT
  1444. NEXT Count%
  1445. SELECT CASE PreserveSprite%
  1446.   CASE IS = 0
  1447.     SpriteLoaded(Object(ObjectNumber%)) = 0
  1448.   CASE ELSE
  1449. END SELECT
  1450. END SUB
  1451.  
  1452. FUNCTION GETX% (XCord%, YCord%)
  1453. 'Select the plane from which we must read the pixel color:
  1454. outport &H3CE, 4
  1455. outport &H3CF, (XCord% AND 3)
  1456. DEF SEG = &HA000&
  1457. GETX% = PEEK((VGAWidthBytes% * YCord%) + (XCord% \ 4) + ActiveStart&)
  1458. DEF SEG
  1459. END FUNCTION
  1460.  
  1461. SUB GPRINT (DUMMY$)
  1462. SELECT CASE LEN(DUMMY$)
  1463.   CASE IS = 0
  1464.     CursorX% = 0
  1465.     CursorY% = CursorY% + 1
  1466.     SELECT CASE CursorY%
  1467.       CASE IS < 0
  1468.         CursorY% = 0
  1469.       CASE IS > ((VGAHeight% / 5) - 1)
  1470.         CursorX% = ((VGAWidth% / 5) - 1)
  1471.         CursorY% = ((VGAHeight% / 5) - 1)
  1472.     END SELECT
  1473.   CASE ELSE
  1474.     SELECT CASE CursorX%
  1475.       CASE IS < 0
  1476.         CursorX% = 0
  1477.       CASE IS > ((VGAWidth% / 5) - 1)
  1478.         CursorX% = ((VGAWidth% / 5) - 1)
  1479.     END SELECT
  1480.     SELECT CASE CursorY%
  1481.       CASE IS < 0
  1482.         CursorY% = 0
  1483.       CASE IS > ((VGAHeight% / 5) - 1)
  1484.         CursorY% = ((VGAHeight% / 5) - 1)
  1485.     END SELECT
  1486.     Count% = 1
  1487.     DO
  1488.       Parse$ = MID$(DUMMY$, Count%, 1)
  1489.       Count% = Count% + 1
  1490.       FOR CountY% = 1 TO 5
  1491.         FOR CountX% = 1 TO 5
  1492.           SELECT CASE CharSet(ASC(Parse$), CountY%, CountX%)
  1493.             CASE IS = 1
  1494.               PSETX ((CursorX% * 5) + (CountX% - 1)), ((CursorY% * 5) + (CountY% - 1)), CurrentColour%
  1495.           END SELECT
  1496.       NEXT CountX%, CountY%
  1497.       CursorX% = CursorX% + 1
  1498.       SELECT CASE CursorX%
  1499.         CASE IS > ((VGAWidth% / 5) - 1)
  1500.           CursorX% = 0
  1501.           CursorY% = CursorY% + 1
  1502.       END SELECT
  1503.       SELECT CASE CursorY%
  1504.         CASE IS > ((VGAHeight% / 5) - 1)
  1505.           CursorX% = ((VGAWidth% / 5) - 1)
  1506.           CursorY% = ((VGAHeight% / 5) - 1)
  1507.       END SELECT
  1508.     LOOP UNTIL Count% > LEN(DUMMY$)
  1509. END SELECT
  1510. END SUB
  1511.  
  1512. FUNCTION inport$ (Addr&)
  1513. WORD& = ((INP(Addr& + 1) * 256) + INP(Addr&))
  1514. inport$ = HEX$(WORD&)
  1515. END FUNCTION
  1516.  
  1517. SUB LoadBG (filename$, headersize%)
  1518. BGFile% = FREEFILE
  1519. OPEN filename$ FOR BINARY AS #BGFile%
  1520. header$ = SPACE$(headersize%)
  1521. GET #BGFile%, , header$
  1522. BGWidth% = ((ASC(LEFT$(header$, 1)) * 256) + ASC(MID$(header$, 2, 1)))
  1523. BGHeight% = ((ASC(MID$(header$, 3, 1)) * 256) + ASC(RIGHT$(header$, 1)))
  1524. BGSize& = (CLNG(BGWidth%) * BGHeight%)
  1525. End32K% = (32767 - (32767 MOD BGWidth%))
  1526. End4K% = (4096 - (4096 MOD BGWidth%))
  1527.  
  1528. 'The file being read should not exceed 262,144 bytes
  1529.  
  1530. 'Some of the redimming below are not really needed.  They are
  1531. 'placed there to free memory (if possible).
  1532.  
  1533. 'The last Counter& command in each CASE are not needed either.
  1534. 'They are there in case future commands in this sub-routine
  1535. 'accesses Counter&.
  1536.  
  1537. SELECT CASE ((BGSize& - 1) \ 32767)
  1538.   CASE IS = 0
  1539.     REDIM Background0(0 TO 0) AS Custom32K
  1540.     REDIM Background1(0 TO 0) AS Custom32K
  1541.     REDIM Background2(0 TO 0) AS Custom32K
  1542.     REDIM Background3(0 TO 0) AS Custom32K
  1543.     REDIM Background4(0 TO 0) AS Custom4K
  1544.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1545.     Counter& = End32K% + Counter&
  1546.   CASE IS = 1
  1547.     REDIM Background0(0 TO 1) AS Custom32K
  1548.     REDIM Background1(0 TO 0) AS Custom32K
  1549.     REDIM Background2(0 TO 0) AS Custom32K
  1550.     REDIM Background3(0 TO 0) AS Custom32K
  1551.     REDIM Background4(0 TO 0) AS Custom4K
  1552.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1553.     Counter& = End32K% + Counter&
  1554.     GET #BGFile%, (Counter& + headersize% + 1), Background0(1).Each32K
  1555.     Counter& = End32K% + Counter&
  1556.   CASE IS = 2
  1557.     REDIM Background0(0 TO 1) AS Custom32K
  1558.     REDIM Background1(0 TO 0) AS Custom32K
  1559.     REDIM Background2(0 TO 0) AS Custom32K
  1560.     REDIM Background3(0 TO 0) AS Custom32K
  1561.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1562.     Counter& = End32K% + Counter&
  1563.     GET #BGFile%, (Counter& + headersize% + 1), Background0(1).Each32K
  1564.     Counter& = End32K% + Counter&
  1565.     GET #BGFile%, (Counter& + headersize% + 1), Background1(0).Each32K
  1566.     Counter& = End32K% + Counter&
  1567.   CASE IS = 3
  1568.     REDIM Background0(0 TO 1) AS Custom32K
  1569.     REDIM Background1(0 TO 1) AS Custom32K
  1570.     REDIM Background2(0 TO 0) AS Custom32K
  1571.     REDIM Background3(0 TO 0) AS Custom32K
  1572.     REDIM Background4(0 TO 0) AS Custom4K
  1573.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1574.     Counter& = End32K% + Counter&
  1575.     GET #BGFile%, (Counter& + headersize% + 1), Background0(1).Each32K
  1576.     Counter& = End32K% + Counter&
  1577.     GET #BGFile%, (Counter& + headersize% + 1), Background1(0).Each32K
  1578.     Counter& = End32K% + Counter&
  1579.     GET #BGFile%, (Counter& + headersize% + 1), Background1(1).Each32K
  1580.     Counter& = End32K% + Counter&
  1581.   CASE IS = 4
  1582.     REDIM Background0(0 TO 1) AS Custom32K
  1583.     REDIM Background1(0 TO 1) AS Custom32K
  1584.     REDIM Background2(0 TO 0) AS Custom32K
  1585.     REDIM Background3(0 TO 0) AS Custom32K
  1586.     REDIM Background4(0 TO 0) AS Custom4K
  1587.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1588.     Counter& = End32K% + Counter&
  1589.     GET #BGFile%, (Counter& + headersize% + 1), Background0(1).Each32K
  1590.     Counter& = End32K% + Counter&
  1591.     GET #BGFile%, (Counter& + headersize% + 1), Background1(0).Each32K
  1592.     Counter& = End32K% + Counter&
  1593.     GET #BGFile%, (Counter& + headersize% + 1), Background1(1).Each32K
  1594.     Counter& = End32K% + Counter&
  1595.     GET #BGFile%, (Counter& + headersize% + 1), Background2(0).Each32K
  1596.     Counter& = End32K% + Counter&
  1597.   CASE IS = 5
  1598.     REDIM Background0(0 TO 1) AS Custom32K
  1599.     REDIM Background1(0 TO 1) AS Custom32K
  1600.     REDIM Background2(0 TO 1) AS Custom32K
  1601.     REDIM Background3(0 TO 0) AS Custom32K
  1602.     REDIM Background4(0 TO 0) AS Custom4K
  1603.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1604.     Counter& = End32K% + Counter&
  1605.     GET #BGFile%, (Counter& + headersize% + 1), Background0(1).Each32K
  1606.     Counter& = End32K% + Counter&
  1607.     GET #BGFile%, (Counter& + headersize% + 1), Background1(0).Each32K
  1608.     Counter& = End32K% + Counter&
  1609.     GET #BGFile%, (Counter& + headersize% + 1), Background1(1).Each32K
  1610.     Counter& = End32K% + Counter&
  1611.     GET #BGFile%, (Counter& + headersize% + 1), Background2(0).Each32K
  1612.     Counter& = End32K% + Counter&
  1613.     GET #BGFile%, (Counter& + headersize% + 1), Background2(1).Each32K
  1614.     Counter& = End32K% + Counter&
  1615.   CASE IS = 6
  1616.     REDIM Background0(0 TO 1) AS Custom32K
  1617.     REDIM Background1(0 TO 1) AS Custom32K
  1618.     REDIM Background2(0 TO 1) AS Custom32K
  1619.     REDIM Background3(0 TO 0) AS Custom32K
  1620.     REDIM Background4(0 TO 0) AS Custom4K
  1621.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1622.     Counter& = End32K% + Counter&
  1623.     GET #BGFile%, (Counter& + headersize% + 1), Background0(1).Each32K
  1624.     Counter& = End32K% + Counter&
  1625.     GET #BGFile%, (Counter& + headersize% + 1), Background1(0).Each32K
  1626.     Counter& = End32K% + Counter&
  1627.     GET #BGFile%, (Counter& + headersize% + 1), Background1(1).Each32K
  1628.     Counter& = End32K% + Counter&
  1629.     GET #BGFile%, (Counter& + headersize% + 1), Background2(0).Each32K
  1630.     Counter& = End32K% + Counter&
  1631.     GET #BGFile%, (Counter& + headersize% + 1), Background2(1).Each32K
  1632.     Counter& = End32K% + Counter&
  1633.     GET #BGFile%, (Counter& + headersize% + 1), Background3(0).Each32K
  1634.     Counter& = End32K% + Counter&
  1635.   CASE IS = 7
  1636.     REDIM Background0(0 TO 1) AS Custom32K
  1637.     REDIM Background1(0 TO 1) AS Custom32K
  1638.     REDIM Background2(0 TO 1) AS Custom32K
  1639.     REDIM Background3(0 TO 1) AS Custom32K
  1640.     REDIM Background4(0 TO 0) AS Custom4K
  1641.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1642.     Counter& = End32K% + Counter&
  1643.     GET #BGFile%, (Counter& + headersize% + 1), Background0(1).Each32K
  1644.     Counter& = End32K% + Counter&
  1645.     GET #BGFile%, (Counter& + headersize% + 1), Background1(0).Each32K
  1646.     Counter& = End32K% + Counter&
  1647.     GET #BGFile%, (Counter& + headersize% + 1), Background1(1).Each32K
  1648.     Counter& = End32K% + Counter&
  1649.     GET #BGFile%, (Counter& + headersize% + 1), Background2(0).Each32K
  1650.     Counter& = End32K% + Counter&
  1651.     GET #BGFile%, (Counter& + headersize% + 1), Background2(1).Each32K
  1652.     Counter& = End32K% + Counter&
  1653.     GET #BGFile%, (Counter& + headersize% + 1), Background3(0).Each32K
  1654.     Counter& = End32K% + Counter&
  1655.     GET #BGFile%, (Counter& + headersize% + 1), Background3(1).Each32K
  1656.     Counter& = End32K% + Counter&
  1657.   CASE IS = 8
  1658.     REDIM Background0(0 TO 1) AS Custom32K
  1659.     REDIM Background1(0 TO 1) AS Custom32K
  1660.     REDIM Background2(0 TO 1) AS Custom32K
  1661.     REDIM Background3(0 TO 1) AS Custom32K
  1662.     REDIM Background4(0 TO 0) AS Custom4K
  1663.     GET #BGFile%, (Counter& + headersize% + 1), Background0(0).Each32K
  1664.     Counter& = End32K% + Counter&
  1665.     GET #BGFile%, (Counter& + headersize% + 1), Background0(1).Each32K
  1666.     Counter& = End32K% + Counter&
  1667.     GET #BGFile%, (Counter& + headersize% + 1), Background1(0).Each32K
  1668.     Counter& = End32K% + Counter&
  1669.     GET #BGFile%, (Counter& + headersize% + 1), Background1(1).Each32K
  1670.     Counter& = End32K% + Counter&
  1671.     GET #BGFile%, (Counter& + headersize% + 1), Background2(0).Each32K
  1672.     Counter& = End32K% + Counter&
  1673.     GET #BGFile%, (Counter& + headersize% + 1), Background2(1).Each32K
  1674.     Counter& = End32K% + Counter&
  1675.     GET #BGFile%, (Counter& + headersize% + 1), Background3(0).Each32K
  1676.     Counter& = End32K% + Counter&
  1677.     GET #BGFile%, (Counter& + headersize% + 1), Background3(1).Each32K
  1678.     Counter& = End32K% + Counter&
  1679.     GET #BGFile%, (Counter& + headersize% + 1), Background4(0).Each4K
  1680.     Counter& = End4K% + Counter&
  1681. END SELECT
  1682. CLOSE #BGFile%
  1683.  
  1684. END SUB
  1685.  
  1686. SUB LoadCharSet
  1687. CharacterSet$ = SPACE$(5 * 5 * 256)
  1688. FFile% = FREEFILE
  1689. OPEN "5x5Chars.Map" FOR BINARY AS FFile%
  1690. GET #FFile%, , CharacterSet$
  1691. CLOSE #FFile%
  1692. FOR CountC% = 0 TO 255
  1693.   FOR CountY% = 1 TO 5
  1694.     FOR CountX% = 1 TO 5
  1695.       CharSet(CountC%, CountY%, CountX%) = ASC(MID$(CharacterSet$, ((CountC% * 25) + ((CountY% - 1) * 5) + CountX%), 1))
  1696. NEXT CountX%, CountY%, CountC%
  1697. END SUB
  1698.  
  1699. SUB LoadSprites (filename$, SpriteNum%)
  1700. 'All Sprite files are in GN2 format
  1701. SpriteFile% = FREEFILE
  1702. OPEN filename$ FOR BINARY AS #SpriteFile%
  1703. headersize% = 3
  1704. header$ = SPACE$(headersize%)
  1705. GET #SpriteFile%, , header$
  1706. TotalFrames% = ASC(LEFT$(header$, 1))
  1707. SELECT CASE TotalFrames%
  1708.   CASE IS > 15
  1709.     TotalFrames% = 15
  1710. END SELECT
  1711. SpriteWidth% = ASC(MID$(header$, 2, 1))
  1712. SpriteHeight% = ASC(RIGHT$(header$, 1))
  1713. SpriteSize% = (SpriteWidth% * SpriteHeight%)
  1714. OneLessThanTF% = (TotalFrames% - 1)
  1715.  
  1716. SpriteNum% = -1 'Assume no sprites are currently available
  1717. FOR Count% = 0 TO 7
  1718.   SELECT CASE SpriteLoaded(Count%)
  1719.     CASE IS = 0
  1720.       SpriteNum% = Count%
  1721.       EXIT FOR
  1722.   END SELECT
  1723. NEXT Count%
  1724. SELECT CASE SpriteNum%
  1725.   CASE IS = 0
  1726.     REDIM Sprite0(0 TO OneLessThanTF%) AS Custom4K
  1727.     FOR FrameNumber% = 0 TO OneLessThanTF%
  1728.       GET #SpriteFile%, (Counter& + headersize% + 1), Sprite0(FrameNumber%).Each4K
  1729.       Counter& = SpriteSize% + Counter&
  1730.     NEXT FrameNumber%
  1731.   CASE IS = 1
  1732.     REDIM Sprite1(0 TO OneLessThanTF%) AS Custom4K
  1733.     FOR FrameNumber% = 0 TO OneLessThanTF%
  1734.       GET #SpriteFile%, (Counter& + headersize% + 1), Sprite1(FrameNumber%).Each4K
  1735.       Counter& = SpriteSize% + Counter&
  1736.     NEXT FrameNumber%
  1737.   CASE IS = 2
  1738.     REDIM Sprite2(0 TO OneLessThanTF%) AS Custom4K
  1739.     FOR FrameNumber% = 0 TO OneLessThanTF%
  1740.       GET #SpriteFile%, (Counter& + headersize% + 1), Sprite2(FrameNumber%).Each4K
  1741.       Counter& = SpriteSize% + Counter&
  1742.     NEXT FrameNumber%
  1743.   CASE IS = 3
  1744.     REDIM Sprite3(0 TO OneLessThanTF%) AS Custom4K
  1745.     FOR FrameNumber% = 0 TO OneLessThanTF%
  1746.       GET #SpriteFile%, (Counter& + headersize% + 1), Sprite3(FrameNumber%).Each4K
  1747.       Counter& = SpriteSize% + Counter&
  1748.     NEXT FrameNumber%
  1749.   CASE IS = 4
  1750.     REDIM Sprite4(0 TO OneLessThanTF%) AS Custom4K
  1751.     FOR FrameNumber% = 0 TO OneLessThanTF%
  1752.       GET #SpriteFile%, (Counter& + headersize% + 1), Sprite4(FrameNumber%).Each4K
  1753.       Counter& = SpriteSize% + Counter&
  1754.     NEXT FrameNumber%
  1755.   CASE IS = 5
  1756.     REDIM Sprite5(0 TO OneLessThanTF%) AS Custom4K
  1757.     FOR FrameNumber% = 0 TO OneLessThanTF%
  1758.       GET #SpriteFile%, (Counter& + headersize% + 1), Sprite5(FrameNumber%).Each4K
  1759.       Counter& = SpriteSize% + Counter&
  1760.     NEXT FrameNumber%
  1761.   CASE IS = 6
  1762.     REDIM Sprite6(0 TO OneLessThanTF%) AS Custom4K
  1763.     FOR FrameNumber% = 0 TO OneLessThanTF%
  1764.       GET #SpriteFile%, (Counter& + headersize% + 1), Sprite6(FrameNumber%).Each4K
  1765.       Counter& = SpriteSize% + Counter&
  1766.     NEXT FrameNumber%
  1767.   CASE IS = 7
  1768.     REDIM Sprite7(0 TO OneLessThanTF%) AS Custom4K
  1769.     FOR FrameNumber% = 0 TO OneLessThanTF%
  1770.       GET #SpriteFile%, (Counter& + headersize% + 1), Sprite7(FrameNumber%).Each4K
  1771.       Counter& = SpriteSize% + Counter&
  1772.     NEXT FrameNumber%
  1773. END SELECT
  1774.  
  1775. CLOSE #SpriteFile%
  1776.  
  1777. SELECT CASE SpriteNum%
  1778.   CASE 0 TO 7
  1779.     SpriteLoaded(SpriteNum%) = 1
  1780.     MaxSpriteFrame(SpriteNum%) = OneLessThanTF%
  1781.     SpriteWidth(SpriteNum%) = SpriteWidth%
  1782.     SpriteHeight(SpriteNum%) = SpriteHeight%
  1783. END SELECT
  1784. END SUB
  1785.  
  1786. SUB memset (Segment&, Addr&, BYTE%, Size&)
  1787. DEF SEG = Segment&
  1788. FOR Count& = 1 TO Size&
  1789.   POKE Addr& + (Count& - 1), BYTE%
  1790. NEXT Count&
  1791. DEF SEG
  1792. END SUB
  1793.  
  1794. SUB ObjectCopy (FromObject%, ToObject%)
  1795.  
  1796. END SUB
  1797.  
  1798. SUB outport (Addr&, WORD&)
  1799. OUT Addr&, (WORD& MOD 256)
  1800. OUT Addr& + 1, (WORD& \ 256)
  1801. END SUB
  1802.  
  1803. SUB PageCopy (FromPage%, ToPage%)
  1804. ToPage% = ToPage% MOD TotalPages%
  1805. FromPage% = FromPage% MOD TotalPages%
  1806. VGAHeight& = VGAHeight% 'This prevents an overflow error
  1807. ToPageStart& = (ToPage% * VGAWidthBytes% * CLNG(VGAHeight%))
  1808. FromPageStart& = (FromPage% * VGAWidthBytes% * CLNG(VGAHeight))
  1809. CountEnd& = ((VGAWidthBytes% * VGAHeight&) - 1)
  1810.  
  1811. OUT &H3C4, 2
  1812. OUT &H3CE, 4
  1813.  
  1814. DEF SEG = &HA000&
  1815.  
  1816. OUT &H3C5, 1
  1817. OUT &H3CF, 0
  1818. FOR Count& = 0 TO CountEnd&
  1819.   POKE (Count& + ToPageStart&), PEEK(Count& + FromPageStart&)
  1820. NEXT Count&
  1821.  
  1822. OUT &H3C5, 2
  1823. OUT &H3CF, 1
  1824. FOR Count& = 0 TO CountEnd&
  1825.   POKE (Count& + ToPageStart&), PEEK(Count& + FromPageStart&)
  1826. NEXT Count&
  1827.  
  1828. OUT &H3C5, 4
  1829. OUT &H3CF, 2
  1830. FOR Count& = 0 TO CountEnd&
  1831.   POKE (Count& + ToPageStart&), PEEK(Count& + FromPageStart&)
  1832. NEXT Count&
  1833.  
  1834. OUT &H3C5, 8
  1835. OUT &H3CF, 3
  1836. FOR Count& = 0 TO CountEnd&
  1837.   POKE (Count& + ToPageStart&), PEEK(Count& + FromPageStart&)
  1838. NEXT Count&
  1839.  
  1840. DEF SEG
  1841.  
  1842. END SUB
  1843.  
  1844. SUB PAGEFLIP
  1845. SetVisiblePage ActivePage%
  1846. SetActivePage (ActivePage% + 1)
  1847. END SUB
  1848.  
  1849. SUB PSETX (XCord%, YCord%, PixelColor%)
  1850. 'Each address accesses four neighboring pixels, so set
  1851. 'Write Plane Enable according to which pixel we want
  1852. 'to modify.  The plane is determined by the two least
  1853. 'significant bits of the x-coordinate:
  1854. OUT &H3C4, 2
  1855. OUT &H3C5, (2 ^ (XCord% AND 3))
  1856.  
  1857. 'The offset of the pixel into the video segment is
  1858. 'offset = (width * y + x) / 4, and write the given
  1859. 'color to the plane we selected above.  Heed the active
  1860. 'page start selection.
  1861. VGAWidthBytes& = VGAWidthBytes% 'This is quicker than calling up CLNG
  1862.                                 'within the FOR/NEXT loops
  1863. AfterActiveEnd& = ActiveStart& + (VGAWidthBytes& * VGAHeight%)
  1864. Address& = ((VGAWidthBytes% * YCord%) + (XCord% \ 4) + ActiveStart&)
  1865. DEF SEG = &HA000&
  1866. SELECT CASE Address&
  1867.   CASE IS < AfterActiveEnd&
  1868.     POKE Address&, PixelColor%
  1869. END SELECT
  1870. DEF SEG
  1871. END SUB
  1872.  
  1873. SUB PUTBG
  1874. YIncrement32K% = ((32767 - (32767 MOD BGWidth%)) / BGWidth%)
  1875. YIncrement4K% = ((4096 - (4096 MOD BGWidth%)) / BGWidth%)
  1876. BGBlocks% = (BGSize& \ 32767)
  1877.  
  1878. SELECT CASE BGBlocks%
  1879.   CASE 0
  1880.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1881.   CASE 1
  1882.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1883.     PUTX 0, YIncrement32K%, BGWidth%, YIncrement32K%, Background0(1).Each32K, 1
  1884.   CASE 2
  1885.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1886.     PUTX 0, YIncrement32K%, BGWidth%, YIncrement32K%, Background0(1).Each32K, 1
  1887.     PUTX 0, (2 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(0).Each32K, 1
  1888.   CASE 3
  1889.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1890.     PUTX 0, YIncrement32K%, BGWidth%, YIncrement32K%, Background0(1).Each32K, 1
  1891.     PUTX 0, (2 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(0).Each32K, 1
  1892.     PUTX 0, (3 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(1).Each32K, 1
  1893.   CASE 4
  1894.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1895.     PUTX 0, YIncrement32K%, BGWidth%, YIncrement32K%, Background0(1).Each32K, 1
  1896.     PUTX 0, (2 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(0).Each32K, 1
  1897.     PUTX 0, (3 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(1).Each32K, 1
  1898.     PUTX 0, (4 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(0).Each32K, 1
  1899.   CASE 5
  1900.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1901.     PUTX 0, YIncrement32K%, BGWidth%, YIncrement32K%, Background0(1).Each32K, 1
  1902.     PUTX 0, (2 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(0).Each32K, 1
  1903.     PUTX 0, (3 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(1).Each32K, 1
  1904.     PUTX 0, (4 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(0).Each32K, 1
  1905.     PUTX 0, (5 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(1).Each32K, 1
  1906.   CASE 6
  1907.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1908.     PUTX 0, YIncrement32K%, BGWidth%, YIncrement32K%, Background0(1).Each32K, 1
  1909.     PUTX 0, (2 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(0).Each32K, 1
  1910.     PUTX 0, (3 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(1).Each32K, 1
  1911.     PUTX 0, (4 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(0).Each32K, 1
  1912.     PUTX 0, (5 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(1).Each32K, 1
  1913.     PUTX 0, (6 * YIncrement32K%), BGWidth%, YIncrement32K%, Background3(0).Each32K, 1
  1914.   CASE 7
  1915.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1916.     PUTX 0, YIncrement32K%, BGWidth%, YIncrement32K%, Background0(1).Each32K, 1
  1917.     PUTX 0, (2 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(0).Each32K, 1
  1918.     PUTX 0, (3 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(1).Each32K, 1
  1919.     PUTX 0, (4 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(0).Each32K, 1
  1920.     PUTX 0, (5 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(1).Each32K, 1
  1921.     PUTX 0, (6 * YIncrement32K%), BGWidth%, YIncrement32K%, Background3(0).Each32K, 1
  1922.     PUTX 0, (7 * YIncrement32K%), BGWidth%, YIncrement32K%, Background3(1).Each32K, 1
  1923.   CASE 8
  1924.     PUTX 0, 0, BGWidth%, YIncrement32K%, Background0(0).Each32K, 1
  1925.     PUTX 0, YIncrement32K%, BGWidth%, YIncrement32K%, Background0(1).Each32K, 1
  1926.     PUTX 0, (2 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(0).Each32K, 1
  1927.     PUTX 0, (3 * YIncrement32K%), BGWidth%, YIncrement32K%, Background1(1).Each32K, 1
  1928.     PUTX 0, (4 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(0).Each32K, 1
  1929.     PUTX 0, (5 * YIncrement32K%), BGWidth%, YIncrement32K%, Background2(1).Each32K, 1
  1930.     PUTX 0, (6 * YIncrement32K%), BGWidth%, YIncrement32K%, Background3(0).Each32K, 1
  1931.     PUTX 0, (7 * YIncrement32K%), BGWidth%, YIncrement32K%, Background3(1).Each32K, 1
  1932.     PUTX 0, (8 * YIncrement4K%), BGWidth%, YIncrement4K%, Background4(0).Each4K, 1
  1933. END SELECT
  1934. END SUB
  1935.  
  1936. SUB PUTX (XCord%, YCord%, xsize%, ysize%, Buffer$, UseZero%)
  1937.  
  1938. 'If the following address position checks work correctly,
  1939. 'this sub-routine will not write to a video page other
  1940. 'than the current active page.
  1941.  
  1942. DEF SEG = &HA000&
  1943. OUT &H3C4, 2
  1944. VGAWidthBytes& = VGAWidthBytes% 'This is quicker than calling up CLNG
  1945.                                 'within the FOR/NEXT loops
  1946.  
  1947. AfterActiveEnd& = ActiveStart& + (VGAWidthBytes& * VGAHeight%)
  1948.  
  1949. OUT &H3C5, (2 ^ (XCord% AND 3))
  1950. 'The calculations below are the causes for the slowness
  1951. 'of the PUTX sub-routine.
  1952. FOR CountY% = 0 TO (ysize% - 1)
  1953.   FOR CountX% = 0 TO (xsize% - 1) STEP 4
  1954.     PixelColor% = ASC(MID$(Buffer$, ((CountY% * xsize%) + (CountX% + 1)), 1))
  1955.     Address& = ((VGAWidthBytes& * (YCord% + CountY%)) + ((XCord% + CountX%) \ 4) + ActiveStart&)
  1956.     SELECT CASE PixelColor%
  1957.       CASE IS = 0
  1958.         SELECT CASE UseZero%
  1959.           CASE IS = 1
  1960.             SELECT CASE Address&
  1961.               CASE IS < AfterActiveEnd&
  1962.                 POKE Address&, PixelColor%
  1963.             END SELECT
  1964.         END SELECT
  1965.       CASE ELSE
  1966.         SELECT CASE Address&
  1967.           CASE IS < AfterActiveEnd&
  1968.             POKE Address&, PixelColor%
  1969.         END SELECT
  1970.     END SELECT
  1971. NEXT CountX%, CountY%
  1972.  
  1973. OUT &H3C5, (2 ^ ((XCord% + 1) AND 3))
  1974. 'The calculations below are the causes for the slowness
  1975. 'of the PUTX sub-routine.
  1976. FOR CountY% = 0 TO (ysize% - 1)
  1977.   FOR CountX% = 1 TO (xsize% - 1) STEP 4
  1978.     PixelColor% = ASC(MID$(Buffer$, ((CountY% * xsize%) + (CountX% + 1)), 1))
  1979.     Address& = ((VGAWidthBytes& * (YCord% + CountY%)) + ((XCord% + CountX%) \ 4) + ActiveStart&)
  1980.     SELECT CASE PixelColor%
  1981.       CASE IS = 0
  1982.         SELECT CASE UseZero%
  1983.           CASE IS = 1
  1984.             SELECT CASE Address&
  1985.               CASE IS < AfterActiveEnd&
  1986.                 POKE Address&, PixelColor%
  1987.             END SELECT
  1988.         END SELECT
  1989.       CASE ELSE
  1990.         SELECT CASE Address&
  1991.           CASE IS < AfterActiveEnd&
  1992.             POKE Address&, PixelColor%
  1993.         END SELECT
  1994.     END SELECT
  1995. NEXT CountX%, CountY%
  1996.  
  1997. OUT &H3C5, (2 ^ ((XCord% + 2) AND 3))
  1998. 'The calculations below are the causes for the slowness
  1999. 'of the PUTX sub-routine.
  2000. FOR CountY% = 0 TO (ysize% - 1)
  2001.   FOR CountX% = 2 TO (xsize% - 1) STEP 4
  2002.     PixelColor% = ASC(MID$(Buffer$, ((CountY% * xsize%) + (CountX% + 1)), 1))
  2003.     Address& = ((VGAWidthBytes& * (YCord% + CountY%)) + ((XCord% + CountX%) \ 4) + ActiveStart&)
  2004.     SELECT CASE PixelColor%
  2005.       CASE IS = 0
  2006.         SELECT CASE UseZero%
  2007.           CASE IS = 1
  2008.             SELECT CASE Address&
  2009.               CASE IS < AfterActiveEnd&
  2010.                 POKE Address&, PixelColor%
  2011.             END SELECT
  2012.         END SELECT
  2013.       CASE ELSE
  2014.         SELECT CASE Address&
  2015.           CASE IS < AfterActiveEnd&
  2016.             POKE Address&, PixelColor%
  2017.         END SELECT
  2018.     END SELECT
  2019. NEXT CountX%, CountY%
  2020.  
  2021. OUT &H3C5, (2 ^ ((XCord% + 3) AND 3))
  2022. 'The calculations below are the causes for the slowness
  2023. 'of the PUTX sub-routine.
  2024. FOR CountY% = 0 TO (ysize% - 1)
  2025.   FOR CountX% = 3 TO (xsize% - 1) STEP 4
  2026.     PixelColor% = ASC(MID$(Buffer$, ((CountY% * xsize%) + (CountX% + 1)), 1))
  2027.     Address& = ((VGAWidthBytes& * (YCord% + CountY%)) + ((XCord% + CountX%) \ 4) + ActiveStart&)
  2028.     SELECT CASE PixelColor%
  2029.       CASE IS = 0
  2030.         SELECT CASE UseZero%
  2031.           CASE IS = 1
  2032.             SELECT CASE Address&
  2033.               CASE IS < AfterActiveEnd&
  2034.                 POKE Address&, PixelColor%
  2035.             END SELECT
  2036.         END SELECT
  2037.       CASE ELSE
  2038.         SELECT CASE Address&
  2039.           CASE IS < AfterActiveEnd&
  2040.             POKE Address&, PixelColor%
  2041.         END SELECT
  2042.     END SELECT
  2043. NEXT CountX%, CountY%
  2044.  
  2045. DEF SEG
  2046. END SUB
  2047.  
  2048. SUB ReadyFrame (Object%, Repeat%, Direction%, SX%, SY%, EX%, EY%)
  2049. ObjectUseCount(Object%) = ObjectUseCount(Object%) + 1
  2050. SpriteNum% = Object(Object%)
  2051. ObjectLock(Object%) = 1
  2052. ObjectRepeat(Object%) = ObjectRepeat(Object%) + 1
  2053. SELECT CASE MaxFrameNumber(Object%)
  2054.   CASE IS = 0
  2055.     Direction% = 0
  2056. END SELECT
  2057. SELECT CASE ObjectRepeat(Object%)
  2058.   CASE IS > Repeat%
  2059.     ObjectRepeat(Object%) = 0
  2060.   CASE ELSE
  2061.     CurrentFrame(Object%) = LastFrame(Object%)
  2062.     ObjectUseCount(Object%) = ObjectLastCount(Object%)
  2063. END SELECT
  2064. SELECT CASE ObjectUseCount(Object%)
  2065.   CASE IS < 0
  2066.     Numerator% = 0
  2067.   CASE ELSE
  2068.     Numerator% = ObjectUseCount(Object%) + 1
  2069. END SELECT
  2070. SELECT CASE Direction%
  2071.   CASE IS <= 0 'One frame
  2072.     NewFrame% = ABS(Direction%)
  2073.     ObjectLock(Object%) = 0
  2074.     DrawFrame SpriteNum%, NewFrame%, SX%, SY%
  2075.     ObjectLock(Object%) = 0
  2076.   CASE IS = 1 'Forward
  2077.     NewFrame% = CurrentFrame(Object%) + 1
  2078.     SELECT CASE NewFrame%
  2079.       CASE IS = MaxFrameNumber(SpriteNum%)
  2080.         XCord% = (SX% + ((Numerator% / MaxFrameNumber(Object%)) * (EX% - SX%)))
  2081.         YCord% = (SY% + ((Numerator% / MaxFrameNumber(Object%)) * (EY% - SY%)))
  2082.         DrawFrame SpriteNum%, NewFrame%, XCord%, YCord%
  2083.         ObjectLock(Object%) = 2
  2084.       CASE IS < (MaxFrameNumber(SpriteNum%))
  2085.         XCord% = (SX% + ((Numerator% / MaxFrameNumber(Object%)) * (EX% - SX%)))
  2086.         YCord% = (SY% + ((Numerator% / MaxFrameNumber(Object%)) * (EY% - SY%)))
  2087.         DrawFrame SpriteNum%, NewFrame%, XCord%, YCord%
  2088.       CASE ELSE
  2089.         ObjectLock(Object%) = 0
  2090.     END SELECT
  2091.   CASE IS = 2 'Backward
  2092.     SELECT CASE CurrentFrame(Object%)
  2093.       CASE IS = -1
  2094.         CurrentFrame(Object%) = MaxFrameNumber(Object%) + 1
  2095.     END SELECT
  2096.     NewFrame% = CurrentFrame(Object%) - 1
  2097.     SELECT CASE NewFrame%
  2098.       CASE IS > 0
  2099.         XCord% = (SX% + ((Numerator% / MaxFrameNumber(Object%)) * (EX% - SX%)))
  2100.         YCord% = (SY% + ((Numerator% / MaxFrameNumber(Object%)) * (EY% - SY%)))
  2101.         DrawFrame SpriteNum%, NewFrame%, XCord%, YCord%
  2102.       CASE IS = 0
  2103.         XCord% = (SX% + ((Numerator% / MaxFrameNumber(Object%)) * (EX% - SX%)))
  2104.         YCord% = (SY% + ((Numerator% / MaxFrameNumber(Object%)) * (EY% - SY%)))
  2105.         DrawFrame SpriteNum%, NewFrame%, XCord%, YCord%
  2106.         ObjectLock(Object%) = 2
  2107.       CASE ELSE
  2108.         ObjectLock(Object%) = 0
  2109.     END SELECT
  2110. END SELECT
  2111. SELECT CASE ObjectLock(Object%)
  2112.   CASE IS = 1
  2113.     LastFrame(Object%) = CurrentFrame(Object%)
  2114.     CurrentFrame(Object%) = NewFrame%
  2115.     ObjectLastCount(Object%) = ObjectUseCount(Object%)
  2116.   CASE IS = 2
  2117.     LastFrame(Object%) = CurrentFrame(Object%)
  2118.     CurrentFrame(Object%) = NewFrame%
  2119.     ObjectLastCount(Object%) = ObjectUseCount(Object%)
  2120.     SELECT CASE ObjectRepeat(Object%)
  2121.       CASE IS >= Repeat%
  2122.         CurrentFrame(Object%) = -1
  2123.         LastFrame(Object%) = -1
  2124.         ObjectUseCount(Object%) = -1
  2125.         ObjectLastCount(Object%) = -1
  2126.         ObjectRepeat(Object%) = -1
  2127.         ObjectSX(Object%) = 0
  2128.         ObjectEX(Object%) = 0
  2129.         ObjectSY(Object%) = 0
  2130.         ObjectEY(Object%) = 0
  2131.     END SELECT
  2132.   CASE ELSE
  2133.     CurrentFrame(Object%) = -1
  2134.     LastFrame(Object%) = -1
  2135.     ObjectUseCount(Object%) = -1
  2136.     ObjectLastCount(Object%) = -1
  2137.     ObjectRepeat(Object%) = -1
  2138.     ObjectSX(Object%) = 0
  2139.     ObjectEX(Object%) = 0
  2140.     ObjectSY(Object%) = 0
  2141.     ObjectEY(Object%) = 0
  2142. END SELECT
  2143. END SUB
  2144.  
  2145. SUB RGBLoad
  2146. RGBFile% = FREEFILE
  2147. OPEN "RGB.PAL" FOR BINARY AS #RGBFile%
  2148. RGBPalette$ = SPACE$(768)
  2149. GET #RGBFile%, , RGBPalette$
  2150. CLOSE #RGBFile%
  2151. DIM RGBPal(0 TO 255) AS LONG
  2152. FOR Count% = 0 TO 255
  2153.   Red% = (ASC(MID$(RGBPalette$, ((Count% * 3) + 1), 1)) \ 4)
  2154.   Green% = (ASC(MID$(RGBPalette$, ((Count% * 3) + 2), 1)) \ 4)
  2155.   Blue% = (ASC(MID$(RGBPalette$, ((Count% * 3) + 3), 1)) \ 4)
  2156.   RGBPal(Count%) = (65536 * Blue% + 256 * Green% + Red%)
  2157. NEXT Count%
  2158. PALETTE USING RGBPal
  2159. END SUB
  2160.  
  2161. SUB RGBSave
  2162. RGBFile% = FREEFILE
  2163. OPEN "RGB.PAL" FOR BINARY AS #RGBFile%
  2164. PRINT "Saving";
  2165. FOR CountA% = 0 TO 1
  2166.   FOR CountB% = 0 TO 1
  2167.     FOR CountC% = 0 TO 1
  2168.       FOR CountD% = 0 TO 1
  2169.         FOR CountE% = 0 TO 1
  2170.           FOR CountF% = 0 TO 1
  2171.             FOR CountG% = 0 TO 1
  2172.               FOR CountH% = 0 TO 1
  2173.                 FirstColor% = 0
  2174.                 SecondColor% = 0
  2175.                 ThirdColor% = 0
  2176.                 PaletteColor% = 0
  2177.                 SELECT CASE CountH%
  2178.                   CASE IS = 1
  2179.                     FirstColor% = FirstColor% + (2 ^ 0)
  2180.                 END SELECT
  2181.                 SELECT CASE CountG%
  2182.                   CASE IS = 1
  2183.                     FirstColor% = FirstColor% + (2 ^ 1)
  2184.                 END SELECT
  2185.                 SELECT CASE CountF%
  2186.                   CASE 1
  2187.                     FirstColor% = FirstColor% + (2 ^ 2)
  2188.                 END SELECT
  2189.                 SELECT CASE CountE%
  2190.                   CASE 1
  2191.                     SecondColor% = SecondColor% + (2 ^ 0)
  2192.                 END SELECT
  2193.                 SELECT CASE CountD%
  2194.                   CASE 1
  2195.                     SecondColor% = SecondColor% + (2 ^ 1)
  2196.                 END SELECT
  2197.                 SELECT CASE CountC%
  2198.                   CASE IS = 1
  2199.                     ThirdColor% = ThirdColor% + (2 ^ 0)
  2200.                 END SELECT
  2201.                 SELECT CASE CountB%
  2202.                   CASE IS = 1
  2203.                     ThirdColor% = ThirdColor% + (2 ^ 1)
  2204.                 END SELECT
  2205.                 SELECT CASE CountA%
  2206.                   CASE 1
  2207.                     ThirdColor% = ThirdColor% + (2 ^ 2)
  2208.                 END SELECT
  2209.                 Red% = ((ThirdColor% * 8) / (7 * 8) * 63)
  2210.                 'Switch ThirdColor% above with FirstColor%
  2211.                 'below for RGB mode.  Otherwise, it is
  2212.                 'currently in BGR mode.
  2213.                 Green% = ((SecondColor% * 16) / (3 * 16) * 63)
  2214.                 Blue% = ((FirstColor% * 8) / (7 * 8) * 63)
  2215.                 Red$ = CHR$(Red% * 4)
  2216.                 Green$ = CHR$(Green% * 4)
  2217.                 Blue$ = CHR$(Blue% * 4)
  2218.                 PUT #RGBFile%, , Red$
  2219.                 PUT #RGBFile%, , Green$
  2220.                 PUT #RGBFile%, , Blue$
  2221.                 SELECT CASE (((((CountA%) * 128) + ((CountB%) * 64) + ((CountC%) * 32) + ((CountD%) * 16) + ((CountE%) * 8) + ((CountF%) * 4) + ((CountG%) * 2) + CountH%) + 1) MOD 8)
  2222.                   CASE 0
  2223.                     PRINT ".";
  2224.                 END SELECT
  2225. NEXT CountH%, CountG%, CountF%, CountE%, CountD%, CountC%, CountB%, CountA%
  2226. CLOSE #RGBFile%
  2227. END SUB
  2228.  
  2229. 'Shift byte to the left
  2230. FUNCTION SBL& (DWORD&, Shifter%)
  2231. Number& = DWORD& * (2 ^ Shifter%)
  2232. SELECT CASE Number&
  2233.   CASE IS > 65535
  2234.     Number& = BIND&(RIGHT$(BIN$(Number&), LEN(BIN$(Number&)) - 1))
  2235. END SELECT
  2236. SBL& = Number&
  2237. END FUNCTION
  2238.  
  2239. 'Shift byte to the right
  2240. FUNCTION SBR& (DWORD&, Shifter%)
  2241. SBR& = DWORD& \ (2 ^ Shifter%)
  2242. END FUNCTION
  2243.  
  2244. '
  2245. 'setXXXPage() sets the specified page by multiplying the page number
  2246. 'with the size of one page at the current resolution, then handing the
  2247. 'resulting offset value over to the corresponding setXXXStart()
  2248. 'function.  The first page is number 0.
  2249. '
  2250. SUB SetActivePage (PAGE%)
  2251. PAGE% = PAGE% MOD TotalPages%
  2252. SELECT CASE UseReservedPage%
  2253.   CASE IS = 1
  2254.     SELECT CASE PAGE%
  2255.       CASE IS = ReservedPage%
  2256.         PAGE% = (PAGE% + 1) MOD TotalPages%
  2257.         SELECT CASE PAGE%
  2258.           CASE IS = ReservedPage% 'This mode must only
  2259.             UseReservedPage% = 0  'have one page
  2260.           CASE ELSE
  2261.             SELECT CASE PAGE%
  2262.               CASE IS = VisiblePage%                'This mode must
  2263.                 UseReservedPage% = 0                'only have two
  2264.                 PAGE% = (PAGE% + 1) MOD TotalPages% 'pages
  2265.             END SELECT
  2266.         END SELECT
  2267.     END SELECT
  2268. END SELECT
  2269. ActivePage% = PAGE%
  2270. PAGE& = PAGE% 'The use of Page& prevents an overflow error.
  2271. SetActiveStart (PAGE& * VGAWidthBytes% * VGAHeight%)
  2272. END SUB
  2273.  
  2274. '
  2275. 'SetActiveStart tells our graphics operations which address
  2276. 'in video memory should be considered the top left corner.
  2277. '
  2278. SUB SetActiveStart (offset&)
  2279. ActiveStart& = offset&
  2280. END SUB
  2281.  
  2282. SUB SetObject (Object%, Repeat%, Direction%, SX%, SY%, EX%, EY%)
  2283. SpriteNum% = Object(Object%)
  2284. SELECT CASE ObjectLock(Object%)
  2285.   CASE IS = 0
  2286.     SELECT CASE (EX% + SpriteWidth(SpriteNum%))
  2287.       CASE IS > VGAWidth%
  2288.         EX% = VGAWidth% - SpriteWidth(SpriteNum%)
  2289.     END SELECT
  2290.     SELECT CASE (EY% + SpriteHeight(SpriteNum%))
  2291.       CASE IS > VGAHeight%
  2292.         EY% = VGAHeight% - SpriteHeight(SpriteNum%)
  2293.     END SELECT
  2294.     ObjectRepeat(Object%) = -1
  2295.     ObjectSX(Object%) = SX%
  2296.     ObjectEX(Object%) = EX%
  2297.     ObjectSY(Object%) = SY%
  2298.     ObjectEY(Object%) = EY%
  2299.     ObjectLock(SpriteNum%) = 1
  2300.     MaxFrameNumber(Object%) = MaxSpriteFrame(SpriteNum%)
  2301.     CurrentFrame(Object%) = -1
  2302.     LastFrame(Object%) = -1
  2303.     ObjectUseCount(Object%) = -1
  2304.     ObjectLastCount(Object%) = -1
  2305. END SELECT
  2306. ReadyFrame Object%, Repeat%, Direction%, SX%, SY%, EX%, EY%
  2307. END SUB
  2308.  
  2309. '
  2310. 'setXXXPage() sets the specified page by multiplying the page number
  2311. 'with the size of one page at the current resolution, then handing the
  2312. 'resulting offset value over to the corresponding setXXXStart()
  2313. 'function.  The first page is number 0.
  2314. '
  2315. SUB SetVisiblePage (PAGE%)
  2316. PAGE% = PAGE% MOD TotalPages%
  2317. VisiblePage% = PAGE%
  2318. PAGE& = PAGE% 'The use of Page& prevents an overflow error.
  2319. SetVisibleStart (PAGE& * VGAWidthBytes% * VGAHeight%)
  2320. END SUB
  2321.  
  2322. '
  2323. 'SetVisibleStart tells the VGA from which byte to fetch the first
  2324. 'pixel when starting refresh at the top of the screen.
  2325. '
  2326. SUB SetVisibleStart (offset&)
  2327. VisibleStart& = offset&
  2328.  
  2329. 'Here's the WaitRetrace routine
  2330. WaitRetrace
  2331.  
  2332. outport &H3D4, &HC  'Set high byte
  2333. outport &H3D5, SBR(VisibleStart&, 8)
  2334. outport &H3D4, &HD
  2335. outport &H3D5, VisibleStart& AND &HFF
  2336. END SUB
  2337.  
  2338. SUB VGA (ModeName$)
  2339. SELECT CASE ModeName$
  2340.   CASE IS = "256x200x256"
  2341.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2342.     outport &H3D4, &H2C11  'Second, turn off write protect
  2343.     OUT &H3C2, &HE3        'Dot clock
  2344.     outport &H3D4, &H5F00  'Horizontal total
  2345.     outport &H3D4, &H3F01  'Horizontal displayed
  2346.     outport &H3D4, &H4202  'Horizontal blanking start
  2347.     outport &H3D4, &H9F03& 'Horizontal blanking end
  2348.     outport &H3D4, &H4C04  'Horizontal sync/retrace start
  2349.     outport &H3D4, &H5     'Horizontal sync/retrace end
  2350.     outport &H3D4, &H2013  'Offset/logical width
  2351.     VGAWidth% = 256
  2352.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2353.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2354.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2355.     SetActivePage 1        '(for use with multipage modes)
  2356.     ModeName$ = "256x200x256"
  2357.  
  2358.   CASE IS = "256x224x256"
  2359.     'Note: This mode may require monitors that
  2360.     '      support adjustible vertical height
  2361.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2362.     outport &H3D4, &H2C11  'Second, turn off write protect
  2363.     OUT &H3C2, &HE3        'Dot clock
  2364.     outport &H3D4, &H5F00  'Horizontal total
  2365.     outport &H3D4, &H3F01  'Horizontal displayed
  2366.     outport &H3D4, &H4002  'Horizontal blanking start
  2367.     outport &H3D4, &H8203& 'Horizontal blanking end
  2368.     outport &H3D4, &H4A04  'Horizontal sync/retrace start
  2369.     outport &H3D4, &H9A05& 'Horizontal sync/retrace end
  2370.     outport &H3D4, &HB06   'Vertical total
  2371.     outport &H3D4, &H3E07  'Overflow (bit 8 of vertical counts)
  2372.     outport &H3D4, &H4109  'Maximum scanline/character height
  2373.     outport &H3D4, &HDA10& 'Vertical sync/retrace start
  2374.     outport &H3D4, &H9C11& 'Vertical sync/retrace end and protect cr0-cr7
  2375.     outport &H3D4, &HBF12& 'Vertical displayed
  2376.     outport &H3D4, &H2013  'Offset/logical width
  2377.     outport &H3D4, &HC715& 'Vertical blanking start
  2378.     outport &H3D4, &H416   'Vertical blanking end
  2379.     VGAWidth% = 256
  2380.     VGAHeight% = 224
  2381.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2382.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2383.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2384.     SetActivePage 1        '(for use with multipage modes)
  2385.     ModeName$ = "256x224x256"
  2386.  
  2387.   CASE IS = "256x240x256"
  2388.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2389.     outport &H3D4, &H2C11  'Second, turn off write protect
  2390.     OUT &H3C2, &HE3        'Dot clock
  2391.     outport &H3D4, &H5F00  'Horizontal total
  2392.     outport &H3D4, &H3F01  'Horizontal displayed
  2393.     outport &H3D4, &H4202  'Horizontal blanking start
  2394.     outport &H3D4, &H9F03& 'Horizontal blanking end
  2395.     outport &H3D4, &H4C04  'Horizontal sync/retrace start
  2396.     outport &H3D4, &H5     'Horizontal sync/retrace end
  2397.     outport &H3D4, &HD06   'Vertical total
  2398.     outport &H3D4, &H3E07  'Overflow (bit 8 of vertical counts)
  2399.     outport &H3D4, &H4109  'Maximum scanline/character height
  2400.     outport &H3D4, &HEA10& 'Vertical sync/retrace start
  2401.     outport &H3D4, &HAC11& 'Vertical sync/retrace end and protect cr0-cr7
  2402.     outport &H3D4, &HDF12& 'Vertical displayed
  2403.     outport &H3D4, &H2013  'Offset/logical width
  2404.     outport &H3D4, &HE715& 'Vertical blanking start
  2405.     outport &H3D4, &H616   'Vertical blanking end
  2406.     VGAWidth% = 256
  2407.     VGAHeight% = 240
  2408.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2409.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2410.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2411.     SetActivePage 1        '(for use with multipage modes)
  2412.     ModeName$ = "256x240x256"
  2413.  
  2414.   CASE IS = "256x256x256"
  2415.     'Note: This mode may require monitors that
  2416.     '      support adjustible vertical height
  2417.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2418.     outport &H3D4, &H2C11  'Second, turn off write protect
  2419.     OUT &H3C2, &HE3        'Dot clock
  2420.     outport &H3D4, &H5F00  'Horizontal total
  2421.     outport &H3D4, &H3F01  'Horizontal displayed
  2422.     outport &H3D4, &H4002  'Horizontal blanking start
  2423.     outport &H3D4, &H8203& 'Horizontal blanking end
  2424.     outport &H3D4, &H4A04  'Horizontal sync/retrace start
  2425.     outport &H3D4, &H9A05& 'Horizontal sync/retrace end
  2426.     outport &H3D4, &H2306  'Vertical total
  2427.     outport &H3D4, &HB207& 'Overflow (bit 8 of vertical counts)
  2428.     outport &H3D4, &H6109  'Maximum scanline/character height
  2429.     outport &H3D4, &HA10   'Vertical sync/retrace start
  2430.     outport &H3D4, &HAC11& 'Vertical sync/retrace end and protect cr0-cr7
  2431.     outport &H3D4, &HFF12& 'Vertical displayed
  2432.     outport &H3D4, &H2013  'Offset/logical width
  2433.     outport &H3D4, &H715   'Vertical blanking start
  2434.     outport &H3D4, &H1A16& 'Vertical blanking end
  2435.     VGAWidth% = 256
  2436.     VGAHeight% = 256
  2437.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2438.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2439.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2440.     SetActivePage 1        '(for use with multipage modes)
  2441.     ModeName$ = "256x256x256"
  2442.  
  2443.   CASE IS = "256x400x256"
  2444.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2445.     outport &H3D4, &H2C11  'Second, turn off write protect
  2446.     OUT &H3C2, &HE3        'Dot clock
  2447.     outport &H3D4, &H5F00  'Horizontal total
  2448.     outport &H3D4, &H3F01  'Horizontal displayed
  2449.     outport &H3D4, &H4202  'Horizontal blanking start
  2450.     outport &H3D4, &H9F03& 'Horizontal blanking end
  2451.     outport &H3D4, &H4C04  'Horizontal sync/retrace start
  2452.     outport &H3D4, &H5     'Horizontal sync/retrace end
  2453.     outport &H3D4, &H4009  'Maximum scanline/character height
  2454.     outport &H3D4, &H2013  'Offset/logical width
  2455.     VGAWidth% = 256
  2456.     VGAHeight% = 400
  2457.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2458.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2459.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2460.     SetActivePage 1        '(for use with multipage modes)
  2461.     ModeName$ = "256x400x256"
  2462.  
  2463.   CASE IS = "256x480x256"
  2464.     'Note: This mode may require monitors that
  2465.     '      support adjustible vertical height
  2466.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2467.     outport &H3D4, &H2C11  'Second, turn off write protect
  2468.     OUT &H3C2, &HE3        'Dot clock
  2469.     outport &H3D4, &H5F00  'Horizontal total
  2470.     outport &H3D4, &H3F01  'Horizontal displayed
  2471.     outport &H3D4, &H4202  'Horizontal blanking start
  2472.     outport &H3D4, &H9F03& 'Horizontal blanking end
  2473.     outport &H3D4, &H4C04  'Horizontal sync/retrace start
  2474.     outport &H3D4, &H5     'Horizontal sync/retrace end
  2475.     outport &H3D4, &HD06   'Vertical total
  2476.     outport &H3D4, &H3E07  'Overflow (bit 8 of vertical counts)
  2477.     outport &H3D4, &H4009  'Maximum scanline/character height
  2478.     outport &H3D4, &HEA10& 'Vertical sync/retrace start
  2479.     outport &H3D4, &HAC11& 'Vertical sync/retrace end and protect cr0-cr7
  2480.     outport &H3D4, &HDF12& 'Vertical displayed
  2481.     outport &H3D4, &H2013  'Offset/logical width
  2482.     outport &H3D4, &HE715& 'Vertical blanking start
  2483.     outport &H3D4, &H616   'Vertical blanking end
  2484.     VGAWidth% = 256
  2485.     VGAHeight% = 480
  2486.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2487.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2488.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2489.     SetActivePage 1        '(for use with multipage modes)
  2490.     ModeName$ = "256x480x256"
  2491.  
  2492.   CASE IS = "320x200x256"
  2493.     'Sets mode 13h, then turns it into an unchained (planar), 4-page
  2494.     '320x200x256 mode.
  2495.     SCREEN 0                          'SCREEN 0 is needed to make
  2496.     SCREEN 13                         'the command SCREEN 13 effective
  2497.                                       'because QuickBASIC will not
  2498.                                       'reset the VGA card if QuickBASIC
  2499.                                       'thinks it is still in SCREEN &H13
  2500.                                        
  2501.     RGBLoad                           'Loads the RGB palette
  2502.     LoadCharSet                       'Loads the 5x5 character set
  2503.     COLOUR 255
  2504.     outport &H3C4, &H604              'Put the chain-4 mode of sequencer off
  2505.     memset &HA000&, 0, 0, &H10000     'SCREEN 13 only clears every
  2506.                                       'fourth byte of each plane
  2507.   
  2508.     OUT &H3D4, &H11                            'Initializes the VGA to
  2509.     TempByte& = (INP(&H3D5) AND &H7F)          'accept any combination
  2510.     outport &H3D4, (&H11 OR SBL(TempByte&, 8)) 'of configuration
  2511.                                                'register settings.
  2512.   
  2513.     outport &H3C4, &H100              'Reset sequencer
  2514.     outport &H3C4, &H300              'Re-reset sequencer
  2515.     OUT &H3C0, &H20                   'Reenable display data
  2516.   
  2517.     outport &H3D4, &H2C11             'Turn off write protect
  2518.     OUT &H3C2, &HE3                   'Dot clock
  2519.     outport &H3D4, &H5F00             'Horizontal total
  2520.     outport &H3D4, &H4F01             'Horizontal displayed
  2521.     outport &H3D4, &H5002             'Horizontal blanking start
  2522.     outport &H3D4, &H8203&            'Horizontal blanking end
  2523.     outport &H3D4, &H5404             'Horizontal sync/retrace start
  2524.     outport &H3D4, &H8005&            'Horizontal sync/retrace end
  2525.     outport &H3D4, &HBF06&            'Vertical total
  2526.     outport &H3D4, &H1F07             'Overflow (bit 8 of vertical counts)
  2527.     outport &H3D4, &H8                'Present row scan
  2528.     outport &H3D4, &H4109             'Maximum scanline/character height
  2529.     outport &H3D4, &H9C10&            'Vertical sync/retrace start
  2530.     outport &H3D4, &H8E11&            'Vertical sync/retrace end and protect cr0-cr7
  2531.     outport &H3D4, &H8F12&            'Vertical displayed
  2532.     outport &H3D4, &H2813             'Offset/logical width
  2533.     outport &H3D4, &H14               'Turn off CRT controller's
  2534.                                       'double-word (or long) mode
  2535.     outport &H3D4, &H9615&            'Vertical blanking start
  2536.     outport &H3D4, &HB916&            'Vertical blanking end
  2537.     outport &H3D4, &HE317&            'Turn on CRT controller's byte mode
  2538.     outport &H3D4, &H14               'Turn off CRT controller's
  2539.                                       'double-word (or long) mode
  2540.   
  2541.     'ActiveStart& specifies the start of the page being accessed by
  2542.     'drawing operations.  VisibleStart& specifies the contents of the
  2543.     'screen start register, i.e. the start of the visible page.
  2544.     'By default, we want screen refreshing and drawing operations
  2545.     'to be based at offset 0 in the video segment.
  2546.     ActiveStart& = 0
  2547.     VisibleStart& = 0
  2548.  
  2549.     VGAWidth% = 320
  2550.     VGAHeight% = 200
  2551.     'Each byte addresses four pixels, so the width of a scan line in
  2552.     '*bytes* is one fourth of the number of pixels on a line.
  2553.     VGAWidthBytes% = (VGAWidth% / 4)
  2554.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2555.     SetVisiblePage 0                  'This sets up the PAGEFLIP sub-routine
  2556.     SetActivePage 1                   '(for use with multipage modes)
  2557.     ModeName$ = "320x200x256"
  2558.   
  2559.   CASE IS = "320x240x256"
  2560.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2561.     outport &H3D4, &H2C11  'Second, turn off write protect
  2562.     OUT &HE3, &HE3         'Dot clock
  2563.     outport &H3D4, &HD06   'Vertical total
  2564.     outport &H3D4, &H3E07  'Overflow (bit 8 of vertical counts)
  2565.     outport &H3D4, &H4109  'Maximum scanline/character height
  2566.     outport &H3D4, &HEA10& 'Vertical sync/retrace start
  2567.     outport &H3D4, &HAC11& 'Vertical sync/retrace end and protect cr0-cr7
  2568.     outport &H3D4, &HDF12& 'Vertical displayed
  2569.     outport &H3D4, &HE715& 'Vertical blanking start
  2570.     outport &H3D4, &H616   'Vertical blanking end
  2571.     VGAHeight% = 240
  2572.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2573.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2574.     SetActivePage 1        '(for use with multipage modes)
  2575.     ModeName$ = "320x240x256"
  2576.  
  2577.   CASE IS = "320x400x256"
  2578.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2579.     outport &H3D4, &H2C11  'Second, turn off write protect
  2580.     OUT &H3C2, &HE3        'Dot clock
  2581.     outport &H3D4, &H4009  'Maximum scanline/character height
  2582.     VGAWidth% = 320
  2583.     VGAHeight% = 400
  2584.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2585.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2586.     SetActivePage 1        '(for use with multipage modes)
  2587.     ModeName$ = "320x400x256"
  2588.  
  2589.   CASE IS = "320x480x256"
  2590.     'Note: This mode may require monitors that
  2591.     '      support adjustible vertical height
  2592.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2593.     outport &H3D4, &H2C11  'Second, turn off write protect
  2594.     OUT &H3C2, &HE3        'Dot clock
  2595.     outport &H3D4, &HD06   'Vertical total
  2596.     outport &H3D4, &H3E07  'Overflow (bit 8 of vertical counts)
  2597.     outport &H3D4, &H4009  'Maximum scanline/character height
  2598.     outport &H3D4, &HEA10& 'Vertical sync/retrace start
  2599.     outport &H3D4, &HAC11& 'Vertical sync/retrace end and protect cr0-cr7
  2600.     outport &H3D4, &HDF12& 'Vertical displayed
  2601.     outport &H3D4, &HE715& 'Vertical blanking start
  2602.     outport &H3D4, &H616   'Vertical blanking end
  2603.     VGAWidth% = 320
  2604.     VGAHeight% = 480
  2605.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2606.     SetVisiblePage 0       'This mode has less
  2607.     SetActivePage 0        'than two pages
  2608.     ModeName$ = "320x480x256"
  2609.  
  2610.   CASE IS = "360x200x256"
  2611.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2612.     outport &H3D4, &H2C11  'Second, turn off write protect
  2613.     OUT &H3C2, &HE7        'Dot clock
  2614.     outport &H3D4, &H6B00  'Horizontal total
  2615.     outport &H3D4, &H5901  'Horizontal displayed
  2616.     outport &H3D4, &H5A02  'Horizontal blanking start
  2617.     outport &H3D4, &H8E03& 'Horizontal blanking end
  2618.     outport &H3D4, &H5E04  'Horizontal sync/retrace start
  2619.     outport &H3D4, &H8A05& 'Horizontal sync/retrace end
  2620.     outport &H3D4, &H2D13  'Offset/logical width
  2621.     VGAWidth% = 360
  2622.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2623.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2624.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2625.     SetActivePage 1        '(for use with multipage modes)
  2626.     ModeName$ = "360x200x256"
  2627.  
  2628.   CASE IS = "360x240x256"
  2629.     'Note: This mode may require monitors that
  2630.     '      support adjustible vertical height
  2631.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2632.     outport &H3D4, &H2C11  'Second, turn off write protect
  2633.     OUT &H3C2, &HE7        'Dot clock
  2634.     outport &H3D4, &H6B00  'Horizontal total
  2635.     outport &H3D4, &H5901  'Horizontal displayed
  2636.     outport &H3D4, &H5A02  'Horizontal blanking start
  2637.     outport &H3D4, &H8E03& 'Horizontal blanking end
  2638.     outport &H3D4, &H5E04  'Horizontal sync/retrace start
  2639.     outport &H3D4, &H8A05& 'Horizontal sync/retrace end
  2640.     outport &H3D4, &HD06   'Vertical total
  2641.     outport &H3D4, &H3E07  'Overflow (bit 8 of vertical counts)
  2642.     outport &H3D4, &H4109  'Maximum scanline/character height
  2643.     outport &H3D4, &HEA10& 'Vertical sync/retrace start
  2644.     outport &H3D4, &HAC11& 'Vertical sync/retrace end and protect cr0-cr7
  2645.     outport &H3D4, &HDF12& 'Vertical displayed
  2646.     outport &H3D4, &H2D13  'Offset/logical width
  2647.     outport &H3D4, &HE715& 'Vertical blanking start
  2648.     outport &H3D4, &H616   'Vertical blanking end
  2649.     VGAWidth% = 360
  2650.     VGAHeight% = 240
  2651.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2652.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2653.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2654.     SetActivePage 1        '(for use with multipage modes)
  2655.     ModeName$ = "360x240x256"
  2656.  
  2657.   CASE IS = "360x270x256"
  2658.     'Note: This mode may require monitors that
  2659.     '      support adjustible vertical height
  2660.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2661.     outport &H3D4, &H2C11  'Second, turn off write protect
  2662.     OUT &H3C2, &HE7        'Dot clock
  2663.     outport &H3D4, &H6B00  'Horizontal total
  2664.     outport &H3D4, &H5901  'Horizontal displayed
  2665.     outport &H3D4, &H5A02  'Horizontal blanking start
  2666.     outport &H3D4, &H8E03& 'Horizontal blanking end
  2667.     outport &H3D4, &H5E04  'Horizontal sync/retrace start
  2668.     outport &H3D4, &H8A05& 'Horizontal sync/retrace end
  2669.     outport &H3D4, &H3006  'Vertical total
  2670.     outport &H3D4, &HF007& 'Overflow (bit 8 of vertical counts)
  2671.     outport &H3D4, &H6109  'Maximum scanline/character height
  2672.     outport &H3D4, &H2010  'Vertical sync/retrace start
  2673.     outport &H3D4, &HA911& 'Vertical sync/retrace end and protect cr0-cr7
  2674.     outport &H3D4, &H1B12  'Vertical displayed
  2675.     outport &H3D4, &H2D13  'Offset/logical width
  2676.     outport &H3D4, &H1F15  'Vertical blanking start
  2677.     outport &H3D4, &H2F16  'Vertical blanking end
  2678.     VGAWidth% = 360
  2679.     VGAHeight% = 270
  2680.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2681.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2682.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2683.     SetActivePage 1        '(for use with multipage modes)
  2684.     ModeName$ = "360x270x256"
  2685.  
  2686.   CASE IS = "376x282x256"
  2687.     'Note: This mode may require monitors that
  2688.     '      support adjustible vertical height
  2689.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2690.     outport &H3D4, &H2C11  'Second, turn off write protect
  2691.     OUT &H3C2, &HE7        'Dot clock
  2692.     outport &H3D4, &H6E00  'Horizontal total
  2693.     outport &H3D4, &H5D01  'Horizontal displayed
  2694.     outport &H3D4, &H5E02  'Horizontal blanking start
  2695.     outport &H3D4, &H9103& 'Horizontal blanking end
  2696.     outport &H3D4, &H6204  'Horizontal sync/retrace start
  2697.     outport &H3D4, &H8F05& 'Horizontal sync/retrace end
  2698.     outport &H3D4, &H6206  'Vertical total
  2699.     outport &H3D4, &HF007& 'Overflow (bit 8 of vertical counts)
  2700.     outport &H3D4, &H6109  'Maximum scanline/character height
  2701.     outport &H3D4, &H3710  'Vertical sync/retrace start
  2702.     outport &H3D4, &H8911& 'Vertical sync/retrace end and protect cr0-cr7
  2703.     outport &H3D4, &H3312  'Vertical displayed
  2704.     outport &H3D4, &H2F13  'Offset/logical width
  2705.     outport &H3D4, &H3C15  'Vertical blanking start
  2706.     outport &H3D4, &H5C16  'Vertical blanking end
  2707.     VGAWidth% = 376
  2708.     VGAHeight% = 282
  2709.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2710.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2711.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2712.     SetActivePage 1        '(for use with multipage modes)
  2713.     ModeName$ = "376x282x256"
  2714.  
  2715.   CASE IS = "376x308x256"
  2716.     'Note: This mode may require monitors that
  2717.     '      support adjustible vertical height
  2718.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2719.     outport &H3D4, &H2C11  'Second, turn off write protect
  2720.     OUT &H3C2, &HE7        'Dot clock
  2721.     outport &H3D4, &H6E00  'Horizontal total
  2722.     outport &H3D4, &H5D01  'Horizontal displayed
  2723.     outport &H3D4, &H5E02  'Horizontal blanking start
  2724.     outport &H3D4, &H9103& 'Horizontal blanking end
  2725.     outport &H3D4, &H6204  'Horizontal sync/retrace start
  2726.     outport &H3D4, &H8F05& 'Horizontal sync/retrace end
  2727.     outport &H3D4, &H6206  'Vertical total
  2728.     outport &H3D4, &HF07   'Overflow (bit 8 of vertical counts)
  2729.     outport &H3D4, &H4009  'Maximum scanline/character height
  2730.     outport &H3D4, &H3710   'Vertical sync/retrace start
  2731.     outport &H3D4, &H8911& 'Vertical sync/retrace end and protect cr0-cr7
  2732.     outport &H3D4, &H3312  'Vertical displayed
  2733.     outport &H3D4, &H2F13  'Offset/logical width
  2734.     outport &H3D4, &H3C15  'Vertical blanking start
  2735.     outport &H3D4, &H5C16& 'Vertical blanking end
  2736.     VGAWidth% = 376
  2737.     VGAHeight% = 308
  2738.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2739.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2740.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2741.     SetActivePage 1        '(for use with multipage modes)
  2742.     ModeName$ = "376x308x256"
  2743.  
  2744.   CASE IS = "360x360x256"
  2745.     'Note: This mode may require monitors that
  2746.     '      support adjustible vertical height
  2747.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2748.     outport &H3D4, &H2C11  'Second, turn off write protect
  2749.     OUT &H3C2, &HE7        'Dot clock
  2750.     outport &H3D4, &H6B00  'Horizontal total
  2751.     outport &H3D4, &H5901  'Horizontal displayed
  2752.     outport &H3D4, &H5A02  'Horizontal blanking start
  2753.     outport &H3D4, &H8E03& 'Horizontal blanking end
  2754.     outport &H3D4, &H5E04  'Horizontal sync/retrace start
  2755.     outport &H3D4, &H8A05& 'Horizontal sync/retrace end
  2756.     outport &H3D4, &H4009  'Maximum scanline/character height
  2757.     outport &H3D4, &H8810& 'Vertical sync/retrace start
  2758.     outport &H3D4, &H8511& 'Vertical sync/retrace end and protect cr0-cr7
  2759.     outport &H3D4, &H6712  'Vertical displayed
  2760.     outport &H3D4, &H2D13  'Offset/logical width
  2761.     outport &H3D4, &H6D15  'Vertical blanking start
  2762.     outport &H3D4, &HBA16& 'Vertical blanking end
  2763.     VGAWidth% = 360
  2764.     VGAHeight% = 360
  2765.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2766.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2767.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2768.     SetActivePage 1        '(for use with multipage modes)
  2769.     ModeName$ = "360x360x256"
  2770.  
  2771.   CASE IS = "360x400x256"
  2772.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2773.     outport &H3D4, &H2C11  'Second, turn off write protect
  2774.     OUT &H3C2, &HE7        'Dot clock
  2775.     outport &H3D4, &H6B00  'Horizontal total
  2776.     outport &H3D4, &H5901  'Horizontal displayed
  2777.     outport &H3D4, &H5A02  'Horizontal blanking start
  2778.     outport &H3D4, &H8E03& 'Horizontal blanking end
  2779.     outport &H3D4, &H5E04  'Horizontal sync/retrace start
  2780.     outport &H3D4, &H8A05& 'Horizontal sync/retrace end
  2781.     outport &H3D4, &H4009  'Maximum scanline/character height
  2782.     outport &H3D4, &H2D13  'Offset/logical width
  2783.     VGAWidth% = 360
  2784.     VGAHeight% = 400
  2785.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2786.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2787.     SetVisiblePage 0       'This mode has less
  2788.     SetActivePage 0        'than two pages
  2789.     ModeName$ = "360x400x256"
  2790.  
  2791.   CASE IS = "360x480x256"
  2792.     'Note: This mode may require monitors that
  2793.     '      support adjustible vertical height
  2794.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2795.     outport &H3D4, &H2C11  'Second, turn off write protect
  2796.     OUT &H3C2, &HE7        'Dot clock
  2797.     outport &H3D4, &H6B00  'Horizontal total
  2798.     outport &H3D4, &H5901  'Horizontal displayed
  2799.     outport &H3D4, &H5A02  'Horizontal blanking start
  2800.     outport &H3D4, &H8E03& 'Horizontal blanking end
  2801.     outport &H3D4, &H5E04  'Horizontal sync/retrace start
  2802.     outport &H3D4, &H8A05& 'Horizontal sync/retrace end
  2803.     outport &H3D4, &HD06   'Vertical total
  2804.     outport &H3D4, &H3E07  'Overflow (bit 8 of vertical counts)
  2805.     outport &H3D4, &H4009  'Maximum scanline/character height
  2806.     outport &H3D4, &HEA10& 'Vertical sync/retrace start
  2807.     outport &H3D4, &HAC11& 'Vertical sync/retrace end and protect cr0-cr7
  2808.     outport &H3D4, &HDF12& 'Vertical displayed
  2809.     outport &H3D4, &H2D13  'Offset/logical width
  2810.     outport &H3D4, &HE715& 'Vertical blanking start
  2811.     outport &H3D4, &H616   'Vertical blanking end
  2812.     VGAWidth% = 360
  2813.     VGAHeight% = 480
  2814.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2815.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2816.     SetVisiblePage 0       'This mode has less
  2817.     SetActivePage 0        'than two pages
  2818.     ModeName$ = "360x480x256"
  2819.  
  2820.   CASE IS = "376x564x256"
  2821.     'Note: This mode may require monitors that
  2822.     '      support adjustible vertical height
  2823.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2824.     outport &H3D4, &H2C11  'Second, turn off write protect
  2825.     OUT &H3C2, &HE7        'Dot clock
  2826.     outport &H3D4, &H6E00  'Horizontal total
  2827.     outport &H3D4, &H5D01  'Horizontal displayed
  2828.     outport &H3D4, &H5E02  'Horizontal blanking start
  2829.     outport &H3D4, &H9103& 'Horizontal blanking end
  2830.     outport &H3D4, &H6204  'Horizontal sync/retrace start
  2831.     outport &H3D4, &H8F05& 'Horizontal sync/retrace end
  2832.     outport &H3D4, &H6206  'Vertical total
  2833.     outport &H3D4, &HF007& 'Overflow (bit 8 of vertical counts)
  2834.     outport &H3D4, &H6009  'Maximum scanline/character height
  2835.     outport &H3D4, &H3710  'Vertical sync/retrace start
  2836.     outport &H3D4, &H8911& 'Vertical sync/retrace end and protect cr0-cr7
  2837.     outport &H3D4, &H3312  'Vertical displayed
  2838.     outport &H3D4, &H2F13  'Offset/logical width
  2839.     outport &H3D4, &H3C15  'Vertical blanking start
  2840.     outport &H3D4, &H5C16  'Vertical blanking end
  2841.     VGAWidth% = 376
  2842.     VGAHeight% = 564
  2843.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2844.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2845.     SetVisiblePage 0       'This mode has less
  2846.     SetActivePage 0        'than two pages
  2847.     ModeName$ = "376x564x256"
  2848.  
  2849.   CASE IS = "400x300x256"
  2850.     'Note: This mode may require monitors that
  2851.     '      support adjustible vertical height
  2852.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2853.     outport &H3D4, &H2C11  'Second, turn off write protect
  2854.     OUT &H3C2, &HA7        'Dot clock
  2855.     outport &H3D4, &H7100  'Horizontal total
  2856.     outport &H3D4, &H6301  'Horizontal displayed
  2857.     outport &H3D4, &H6402  'Horizontal blanking start
  2858.     outport &H3D4, &H9203& 'Horizontal blanking end
  2859.     outport &H3D4, &H6504  'Horizontal sync/retrace start
  2860.     outport &H3D4, &H8205& 'Horizontal sync/retrace end
  2861.     outport &H3D4, &H4606  'Vertical total
  2862.     outport &H3D4, &H1F07  'Overflow (bit 8 of vertical counts)
  2863.     outport &H3D4, &H4009  'Maximum scanline/character height
  2864.     outport &H3D4, &H3110  'Vertical sync/retrace start
  2865.     outport &H3D4, &H8011& 'Vertical sync/retrace end and protect cr0-cr7
  2866.     outport &H3D4, &H2B12  'Vertical displayed
  2867.     outport &H3D4, &H3213  'Offset/logical width
  2868.     outport &H3D4, &H2F15  'Vertical blanking start
  2869.     outport &H3D4, &H4416  'Vertical blanking end
  2870.     VGAWidth% = 400
  2871.     VGAHeight% = 300
  2872.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2873.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2874.     SetVisiblePage 0       'This sets up the PAGEFLIP sub-routine
  2875.     SetActivePage 1        '(for use with multipage modes)
  2876.     ModeName$ = "400x300x256"
  2877.  
  2878.   CASE IS = "400x600x256"
  2879.     'Note: This mode may require monitors that
  2880.     '      support adjustible vertical height
  2881.     VGA "320x200x256"      'First, set the unchained version of mode &H13
  2882.     outport &H3D4, &H2C11  'Second, turn off write protect
  2883.     OUT &H3C2, &HE7        'Dot clock
  2884.     outport &H3D4, &H7000  'Horizontal total
  2885.     outport &H3D4, &H6301  'Horizontal displayed
  2886.     outport &H3D4, &H6402  'Horizontal blanking start
  2887.     outport &H3D4, &H9203& 'Horizontal blanking end
  2888.     outport &H3D4, &H6504  'Horizontal sync/retrace start
  2889.     outport &H3D4, &H8205& 'Horizontal sync/retrace end
  2890.     outport &H3D4, &H7006  'Vertical total
  2891.     outport &H3D4, &HF007& 'Overflow (bit 8 of vertical counts)
  2892.     outport &H3D4, &H6009  'Maximum scanline/character height
  2893.     outport &H3D4, &H5B10  'Vertical sync/retrace start
  2894.     outport &H3D4, &H8C11& 'Vertical sync/retrace end and protect cr0-cr7
  2895.     outport &H3D4, &H5712  'Vertical displayed
  2896.     outport &H3D4, &H3213  'Offset/logical width
  2897.     outport &H3D4, &H5815  'Vertical blanking start
  2898.     outport &H3D4, &H7016  'Vertical blanking end
  2899.     VGAWidth% = 400
  2900.     VGAHeight% = 600
  2901.     VGAWidthBytes% = (VGAWidth% / 4) 'Offset/logical width was changed
  2902.     TotalPages% = 65536 \ (CLNG(VGAWidthBytes%) * VGAHeight%)
  2903.     SetVisiblePage 0       'This mode has less
  2904.     SetActivePage 0        'than two pages
  2905.     ModeName$ = "400x600x256"
  2906.  
  2907.   CASE ELSE
  2908.     VGA "320x200x256"      'Set the unchained version of mode 13h
  2909. END SELECT
  2910. END SUB
  2911.  
  2912. SUB WaitRetrace
  2913.  
  2914. 'WaitRetrace waits until the video
  2915. 'card is in a vertical retrace.
  2916. 'This prevents flickers from
  2917. 'occurring.
  2918.  
  2919. DO
  2920. LOOP UNTIL (INP(&H3DA) AND &H8) = 0
  2921. DO
  2922. LOOP WHILE (INP(&H3DA) AND &H8) = 0
  2923. END SUB
  2924.  
  2925. SUB WARNING
  2926. 'Warning message/loop
  2927. SCREEN 0
  2928. CLS
  2929. WIDTH 80, 25
  2930. COLOR 2
  2931. PRINT "slix version ";
  2932. slixVERSION$ = RIGHT$(STR$(slixVERSION%), LEN(STR$(slixVERSION%)) - 1)
  2933. SELECT CASE LEN(slixVERSION$)
  2934.   CASE IS < 4
  2935.     PRINT "0.";
  2936.     PRINT STRING$((3 - LEN(slixVERSION$)), "0") + slixVERSION$
  2937.   CASE ELSE
  2938.     PRINT LEFT$(slixVERSION$, LEN(slixVERSION$) - 3);
  2939.     PRINT ".";
  2940.     PRINT RIGHT$(slixVERSION$, 3)
  2941. END SELECT
  2942. COLOR 3
  2943. PRINT slixDATE$
  2944. PRINT
  2945. COLOR 9
  2946. PRINT "Written by Lloyd Chang"
  2947. PRINT
  2948. COLOR 6
  2949. PRINT "*** PLEASE READ THE DISCLAIMER BEFORE YOU USE slix ***"
  2950. PRINT
  2951. COLOR 14
  2952. PRINT "!!!USE AT YOUR OWN RISK!!!"
  2953. COLOR 7
  2954. PRINT "This program may ";
  2955. COLOR 28
  2956. PRINT "!!!CRASH!!! ";
  2957. COLOR 7
  2958. PRINT "under certain shells and"
  2959. PRINT "certain operating systems.  ";
  2960. COLOR 14
  2961. PRINT "!!!USE AT YOUR OWN RISK!!!"
  2962. PRINT
  2963. COLOR 10
  2964. PRINT "Some modes may not line up perfectly with certain monitors."
  2965. PRINT "The user might have to adjust the size and position of the"
  2966. PRINT "screen with the monitor's control knobs."
  2967. PRINT
  2968. COLOR 13
  2969. PRINT "Some modes may not work on certain monitors and certain VGA"
  2970. PRINT "cards.  Discoloration may also occur."
  2971. PRINT
  2972. COLOR 11
  2973. PRINT "Recommended: 100% VGA compatible card"
  2974. PRINT "             SVGA monitor"
  2975. PRINT
  2976. COLOR 8
  2977. PRINT "Press [/] three times to continue..."
  2978. COLOR 15
  2979. PRINT "OR HOLD DOWN [Q] TO QUIT (after any " + CHR$(34) + "to continue..." + CHR$(34) + ")"
  2980. DO
  2981.   Keyed$ = INKEY$
  2982.   SELECT CASE Keyed$
  2983.     CASE IS = "Q", "q"
  2984.       END
  2985.     CASE "/"
  2986.       Count% = Count% + 1
  2987.   END SELECT
  2988. LOOP UNTIL Count% = 3
  2989. END SUB
  2990.  
  2991.